CF1067A

前言

人类智慧题,看到取模一眼 Dp。

思路

这道题的主要智慧之处就在于定义状态,我们定义 \(f_{i,j,0/1/2}\) 为现在枚举到第 \(i\) 位且第 \(i\) 位填 \(j\) 并且 \(a_i\) 大于等于小于 \(a_{i-1}\) 的方案数我们可以发现这样的话需要分类讨论。

  • \(f_{i,j,0}\) 时那么我们的 \(a_{i}\) 已经大于 \(a_{i-1}\) 了所以我们对于 \(i-1\) 位已经满足条件了所以 \(a_{i-2}\)\(a_{i-1}\) 之间的关系无论怎么取都没影响。
  • \(f_{i,j,1}\) 其实也和上面同理。
  • \(f_{i,j,2}\) 因为我们的 \(a_{i}\) 无法对 \(a_{i-1}\) 进行贡献所以贡献必须是 \(a_{i-2}\) 给来了,那么就要加上 \(f_{i-1,k,1}+f_{i-1,k,2}\)

但是这样我们发现时间复杂度过不去所以需要用一个前缀和优化,这里只用存最后一位为 \(0\) 的和所有的加起来,然后整体时间复杂度 \(O(n^2)\),稳稳通过。

代码

#include <bits/stdc++.h>
using namespace std ;
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define rep1(i,x,y) for(int i=x;i>=y;i--)
#define fire signed
#define kong putchar(' ')
#define end putchar('\n')
#define in(x) scanf("%lld",&x)
#define lcm(x,y) x*y/__gcd(x,y)
#define il inline
il void print(int x) {
	if(x>=10) print(x/10);
	putchar(x%10+'0');
}
int n;
const int mod=998244353;
const int N=1e5+10;
int a[N];
int f[N][210][3];
int ze[210];
int sum[210];
/*
0 a[i-1]<a[i]
1 a[i-1]=a[i]
2 a[i-1]>a[i]
*/
fire main() {
//	freopen("s.out","r",stdin);
	in(n);
	rep(i,1,n) in(a[i]);
	if(a[1]!=-1) f[1][a[1]][0]=1ll;
	else rep(i,1,200) f[1][i][0]=1;
	rep(i,1,200) sum[i]=(sum[i-1]+f[1][i][1]+f[1][i][2]+f[1][i][0])%mod;
	rep(i,1,200) ze[i]=(ze[i-1]+f[1][i][0])%mod;
	rep(i,2,n) {
		if(a[i]!=-1) {
			if(a[i-1]!=-1) {
				if(a[i]>a[i-1]) f[i][a[i]][0]=(f[i][a[i]][0]+((f[i-1][a[i-1]][1]+f[i-1][a[i-1]][2])%mod+f[i-1][a[i-1]][0])%mod)%mod;
				else if(a[i]==a[i-1]) f[i][a[i]][1]=(f[i][a[i]][1]+((f[i-1][a[i-1]][1]+f[i-1][a[i-1]][2])%mod+f[i-1][a[i-1]][0])%mod)%mod;
				else f[i][a[i]][2]=(f[i][a[i]][2]+(f[i-1][a[i-1]][1]+f[i-1][a[i-1]][2])%mod)%mod;
			} else {
				f[i][a[i]][0]=(f[i][a[i]][0]+sum[a[i]-1])%mod;
				f[i][a[i]][1]=(f[i][a[i]][1]+((f[i-1][a[i]][1]+f[i-1][a[i]][0])%mod+f[i-1][a[i]][2])%mod)%mod;
				f[i][a[i]][2]=(f[i][a[i]][2]+((sum[200]-sum[a[i]])%mod+mod)%mod-((ze[200]-ze[a[i]])%mod+mod)%mod+mod)%mod;
			}
		} else {
			if(a[i-1]!=-1) {
				rep(j,1,200) {
					if(j>a[i-1]) f[i][j][0]=(f[i][j][0]+((f[i-1][a[i-1]][0]+f[i-1][a[i-1]][1])%mod+f[i-1][a[i-1]][2])%mod)%mod;
					else if(j==a[i-1]) f[i][j][1]=(f[i][j][1]+((f[i-1][a[i-1]][0]+f[i-1][a[i-1]][1])%mod+f[i-1][a[i-1]][2])%mod)%mod;
					else f[i][j][2]=(f[i][j][2]+(f[i-1][a[i-1]][1]+f[i-1][a[i-1]][2])%mod)%mod;
				}
			} else {
				rep(j,1,200) {
					f[i][j][0]=(f[i][j][0]+sum[j-1])%mod;
					f[i][j][1]=(f[i][j][1]+(f[i-1][j][1]+f[i-1][j][0])%mod+f[i-1][j][2])%mod;
					f[i][j][2]=(f[i][j][2]+(((sum[200]-sum[j])%mod+mod)%mod-((ze[200]-ze[j])%mod+mod)%mod)+mod)%mod;
				}
			}
		}
		rep(j,1,200) sum[j]=(sum[j-1]+((f[i][j][1]+f[i][j][0])%mod+f[i][j][2])%mod)%mod,ze[j]=(ze[j-1]+f[i][j][0])%mod;
	}
	int res=false;
	rep(i,1,200) res=(res+(f[n][i][1]+f[n][i][2])%mod)%mod;
	print(res);
	return false;
}

posted @ 2024-01-31 11:43  highkj  阅读(12)  评论(0)    收藏  举报