codeforces Array Without Local Maximums
题解
考虑dp,设f[i][j][0/1]表示前i个数,第i个数为j,第i-1个数小于/大于等于j的方案数
考虑转移,假设第i个数选j,第i-1个数选k,则
1.$k>j$ $f[i-1][k][1]=>f[i-1][j][1]$
2.$k=j$ $f[i-1][k][0]+f[i-1][k][1]=>f[i-1][j][1]$
3.$k<j$ $f[i-1][k][0]+f[i-1][k][1]=>f[i-1][j][0]$
前缀和优化即可,效率: $O(200n)$
代码
#include <bits/stdc++.h> using namespace std; const int N=1e5+5,P=998244353; int n,f[205][2],pr[205][2],sf[205][2],a[N],s; int X(int x){return x>=P?x-P:x;} int main(){ cin>>n; for (int i=1;i<=n;i++) scanf("%d",&a[i]); if (~a[1]) f[a[1]][0]=1; else for (int i=1;i<=200;i++) f[i][0]=1; for (int i=2;i<=n;i++){ for (int j=1;j<=200;j++) pr[j][0]=X(pr[j-1][0]+f[j][0]), pr[j][1]=X(pr[j-1][1]+f[j][1]); for (int j=200;j;j--) sf[j][0]=X(sf[j+1][0]+f[j][0]), sf[j][1]=X(sf[j+1][1]+f[j][1]); for (int j=1;j<=200;j++){ f[j][0]=f[j][1]=0; if ((~a[i]) && a[i]!=j) continue; f[j][1]=X(pr[j][0]-pr[j-1][0]+P); f[j][1]=X(f[j][1]+X(pr[j][1]-pr[j-1][1]+P)); f[j][1]=X(f[j][1]+sf[j+1][1]); f[j][0]=X(pr[j-1][0]+pr[j-1][1]); } } for (int i=1;i<=200;i++) s=X(s+f[i][1]); cout<<s<<endl;return 0; }