题解: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\) 种数。转移时分两种情况讨论:

  1. 如果强制要求是 \(mex\),那么 \(dp_{i,j} = dp_{i-1,j-1}\)

  2. 如果要求不是 \(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
*/
posted @ 2025-07-22 21:34  LUlululu1616  阅读(8)  评论(0)    收藏  举报