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;
}