CF1608F MEX counting 口胡

CodeForces 1608F

显然,题目拆掉绝对值,题目变成了对于 a 的前缀的 mex 有区间限制

考虑 DP ,设 dp[i][mex][j] 表示前 i 位 ,Mex(a1,a2,,ai)=mex ,有 j 位数 >mex 的方案数

之所以这样设,是因为我们关心 mex ,并且不关心 >mex 的具体是那些数

容易列出方程:

dp[i][mex][j]={dp[i1][mex1][j]+dp[i][mex1][j+1]×(j+1)dp[i1][mex][j1]+dp[i1][mex][j]×(mex+j)

注意,要先进行第一行的转移,因为第一行涉及到用 dp[i] 转移 dp[i] ,否则会算错

最后的答案就是 Pnmexjdp[n][mex][j] ,那个排列数是为了得到 >mexj 个数的实际方案

dp 第一维显然可以滚掉,那么时间复杂度就是 n2k ,空间 nk

这道题卡常,蒟蒻被卡爆了,这里给出 @GreenSnake 的代码

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
 
const int N = 2000 + 5, K = 100 + 5, Mod = 998244353;
int n = 0, k = 0, b[N] = {}, m = 0, p = 0;
int dp[2][K][N] = {}, g[N] = {}, ans = 0;
 
int main(){
	scanf("%d %d", &n, &k);
	for(int i = 1 ; i <= n ; ++ i) scanf("%d", &b[i]);
	dp[0][k][0] = 1;
	for(int i = 1 ; i <= n ; ++ i){
		p = p ^ 1;
		for(int j = 0 ; j <= i + 1 ; ++ j) g[j] = 0;
		for(int mex = m ; mex <= min(b[i] + k, i) ; ++ mex) for(int j = 0 ; j <= i - mex ; ++ j){
			g[j] = 1ll * g[j + 1] * (j + 1) % Mod;
			if(mex > m && mex - 1 <= b[i - 1] + k) g[j] = (g[j] + dp[p ^ 1][mex - 1 - b[i - 1] + k][j]) % Mod;
			if(mex >= b[i] - k){
				dp[p][mex - b[i] + k][j] = g[j];
				if(mex <= b[i - 1] + k && mex < i){
					if(j + mex < i) dp[p][mex - b[i] + k][j] = (dp[p][mex - b[i] + k][j] + 1ll * dp[p ^ 1][mex - b[i - 1] + k][j] * (j + mex)) % Mod;
					if(j && j + mex - 1 < i) dp[p][mex - b[i] + k][j] = (dp[p][mex - b[i] + k][j] + dp[p ^ 1][mex - b[i - 1] + k][j - 1]) % Mod;
				}
			}
		}
		m = max(m, b[i] - k);
	}
	for(int j = 0 ; j <= n ; ++ j) g[j] = 0;
	for(int mex = m ; mex <= n ; ++ mex) for(int j = 0 ; j <= n - mex ; ++ j){
		if(mex <= b[n] + k) g[j] = (g[j] + dp[p][mex - b[n] + k][j]) % Mod;
		if(j) g[j - 1] = 1ll * g[j] * (n - mex) % Mod;
		else ans = (ans + g[j]) % Mod;
	}
	printf("%d", ans);
	return 0;
}
posted @   _Famiglistimo  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示