题解:AT_arc170_c [ARC170C] Prefix Mex Sequence
这么简单的 arc 我怎么每次都吃不到。
题意:很简单了,不再赘述。
做法:
首先考虑 \(M > N\) 时,我们直接考虑对于 \(mex\) 是唯一的,否则只要不取 \(mex\) 就行,方案数乘上 \(M\)。
然后我们考虑 \(M \le N\) 的时候为什么不能直接乘 \(M\),我们如果在前面直接把 \([0,M]\) 都用了,那么如果现在要求等于 \(mex\),那么就直接爆掉了。
我们换一种方式进行考虑,如果有 \(mex\),那么我们一定会引进一个新数,如果不是 \(mex\),那么都可以,所以我们考虑 \(dp_{i, j}\) 代表前 \(i\) 个用了 \(j\) 种数。转移时分两种情况讨论:
-
如果强制要求是 \(mex\),那么 \(dp_{i,j} = dp_{i-1,j-1}\)。
-
如果要求不是 \(mex\),那么可以选择一种已经有的数,也就是 \(dp_{i,j} = dp_{i-1,j}\times j\);或者选择一种没有的数,同时不能等于 \(mex\),也就是 \(dp_{i,j} = dp_{i-1,j-1}\times(m-j)\)。
按照上述过程转移即可,复杂度 \(O(n^2)\)。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 5005, mod = 998244353;
int n, dp[maxn][maxn], m;
signed main() {
cin >> n >> m;
dp[0][0] = 1;
m++;
for (int i = 1, x; i <= n; i++) {
cin >> x;
if(x) {
for (int j = 1; j <= min(m, i); j++)
dp[i][j] = dp[i - 1][j - 1];
}
else {
for (int j = 0; j <= min(m, i); j++)
dp[i][j] = (dp[i - 1][j] * j + (j ? dp[i - 1][j - 1] * (m - j) % mod : 0)) % mod;
}
// for (int j = 0; j <= i; j++)
// cout << dp[i][j] << " ";
// cout << endl;
}
int ans = 0;
for (int i = 1; i <= min(n, m); i++)
ans = (ans + dp[n][i]) % mod;
cout << ans << endl;
return 0;
}
/*
2
1 3
2 4
*/

浙公网安备 33010602011771号