首先dp[i][j][k]表示当a[i]为j,与i-1关系为k时的可能情况:
k=0表示a[i]<=a[i-1] k==1表示a[i]>a[i-1]
则dp[i][j][0] 即为把所有大于j的数以及k == 0时的加和 最后再加上一个等于j的k == 1的情况
dp[i[[j[[1] 即为把所有小于j的k == 0 或者 k == 1的数加和
而对于a[i]已经确定了的数,则还按照上述方法,只是赋值时只付给j == a[i]的情况就可以了
cf2000分的dp tql Array Without Local Maximums
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10,MOD=998244353;
ll dp[maxn][220][2];
int a[maxn],n;
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n ; i++){
scanf("%d",&a[i]);
}
if(a[1] == -1){
for(int j = 1; j <= 200 ; j++){
dp[1][j][1]=1;
}
}
else dp[1][a[1]][1]=1;
for(int i = 2; i <= n ; i++){
if(a[i] == -1){
ll cur=0;
for(int j = 1; j <= 200 ; j++){
dp[i][j][1]=cur;
cur=(cur+dp[i-1][j][1]+dp[i-1][j][0])%MOD;
}
cur=0;
for(int j = 200 ; j >= 1; j--){
cur=(cur+dp[i-1][j][0])%MOD;
dp[i][j][0]=(cur+dp[i-1][j][1])%MOD;
}
}
else{
ll cur=0;
for(int j = 1; j < a[i] ; j++){
cur=(cur+dp[i-1][j][1]+dp[i-1][j][0])%MOD;
}
dp[i][a[i]][1]=cur;
cur=0;
for(int j = a[i]; j <= 200 ; j++){
cur=(cur+dp[i-1][j][0])%MOD;
}
dp[i][a[i]][0]=(cur+dp[i-1][a[i]][1])%MOD;
}
}
if(a[n] == -1){
ll ans=0;
for(int j = 1; j <= 200 ; j++){
ans=(ans+dp[n][j][0])%MOD;
}printf("%lld\n",ans);
}
else{
printf("%lld\n",dp[n][a[n]][0]);
}
return 0;
}