P2401 不等数列 简单计数DP
P2401 不等数列 简单计数DP
题意
任意\(1-n\)的排列中,将两数之间插入“<”或者">"的关系,问所有排列中恰有\(k\)个"<"的个数
\[k \leq n \leq 1000
\]
分析
因为只问最终的\(n\)个排列,我们可以钦定\(n\)个数的插入顺序由小到大,那么对于已存在的数必然由形如"<,<,>.>,<.<..."组成,经过简单分析可以知道,若插入两边,分别会导致">"数和"<"数加一。插在"<"中间,会导致多一个">",插在">"中间会导致多一个"<"
于是令\(dp[i][j]\)表示前i个数恰好有\(k\)个"<"的方案数,有
\[dp[i + 1][j] += dp[i][j] * (j + 1)\\
dp[i + 1][j + 1] += dp[i][j] * (i - j)
\]
代码
int main(){
int n = rd();
int k = rd();
vector<vector<int>> dp(n + 1,vector<int>(n + 1,0));
dp[1][0] = 1;
for(int i = 1;i < n;i++){
for(int j = 0;j < i;j++){
dp[i + 1][j] += dp[i][j] * (j + 1) % MOD;
dp[i + 1][j] %= MOD;
dp[i + 1][j + 1] += dp[i][j] * (i - j) % MOD;
dp[i + 1][j + 1] %= MOD;
}
}
cout << dp[n][k];
}