1 条题解
-
0
自动搬运
来自洛谷,原作者为

lxy
**搬运于
2025-08-24 22:16:22,当前版本为作者最后更新于2023-01-09 16:40:57,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
分析
一个妙妙的 trick。
首先原题可以转化成求有多少 的排列 满足 , 两边的数同时小于或大于 ,且 。这类题都可以采用插入法 dp。
首先设状态, 表示前 个数,分成 段的方案数。从小到大加入每一个数,考虑现在枚举到 ,若 且 ,则可以分三种情况讨论:
-
新开一段
由于后加入的一定比 大,所以以后插入在 两边的数一定比 大,所以总是合法。此时上一步操作完有 段,所以有 个空可以放。但是如果 说明头不能放,同理 说明尾不能放。因此有转移:
-
接在某一段头/尾
这样的话以后一定会有一个 的数接在 另一侧, 两侧就有一个大于它的和一个小于它的,与题意不符,所以不会有这种情况。
-
将两段连起来
此时 两侧的都比它小,与题意相符。上一步操作完有 段,有 个空可以插,因此有转移:
最后一定是整体一段,故答案为 。
核心代码
const int MAXN=2e3+7; const int mod=1e9+7; int n,s,t,dp[MAXN][MAXN]; signed main(){ qread(n,s,t);int i,j;dp[1][1]=1; for(i=2;i<=n;i++){ for(j=1;j<=i;j++){ if(i!=s&&i!=t) dp[i][j]=(j*(dp[i-1][j+1])%mod+(j-(i>s)-(i>t))*dp[i-1][j-1]%mod)%mod; else dp[i][j]=dp[i-1][j-1]+dp[i-1][j]; } }printf("%lld\n",dp[n][1]); return 0; } -
- 1
信息
- ID
- 5006
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者