CF1067A Array Without Local Maximums

XLI.CF1067A Array Without Local Maximums

这题DEBUG的我心态爆炸……后来发现是一个\(i\)打成\(j\)了……无语。

很容易想到,设\(f[i][j][0/1]\)表示:

到第\(i\)位时,位置\(i\)填入了\(j\),且\(j\geq\text{位置i-1上的数}\)的状态是\(0/1\)的种数。

但这就会有问题:\(\geq\)反过来是\(\leq\),而不是\(<\)

因此我们还要记录一下是否相等。即设\(f[i][j][0/1/2]\)表示:

到第\(i\)位时,位置\(i\)填入了\(j\),且\(j\)相较于上一位是小于/等于/大于。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int lim=200;
int n,num[100100],f[2][210][3],res;
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&num[i]);
	if(num[1]==-1)for(int i=1;i<=lim;i++)f[1][i][0]=1;
	else f[1][num[1]][0]=1;
	for(int i=2;i<=n;i++){
		for(int j=1;j<=lim;j++)f[i&1][j][0]=f[i&1][j][1]=f[i&1][j][2]=0;
		int s;
		s=0;
		for(int j=1;j<=lim;j++){
			if(num[i]==-1||j==num[i])f[i&1][j][0]=s;
			(s+=f[!(i&1)][j][0]+f[!(i&1)][j][1]+f[!(i&1)][j][2])%=mod;
		}
		for(int j=1;j<=lim;j++)if(num[i]==-1||j==num[i])f[i&1][j][1]=(f[!(i&1)][j][0]+f[!(i&1)][j][1]+f[!(i&1)][j][2])%mod;
		s=0;
		for(int j=lim;j>=1;j--){
			if(num[i]==-1||j==num[i])f[i&1][j][2]=s;
			(s+=f[!(i&1)][j][1]+f[!(i&1)][j][2])%=mod;
		}
//		printf("%d:",i);for(int j=1;j<=lim;j++)if(f[i&1][j][0]||f[i&1][j][1])printf("(%d:%d %d)",j,f[i&1][j][0],f[i&1][j][1]);puts("");
	}
	for(int i=1;i<=lim;i++)(res+=f[n&1][i][1]+f[n&1][i][2])%=mod;
	printf("%lld\n",res);
	return 0;
}

原文地址:https://www.cnblogs.com/Troverld/p/14597213.html