【动态规划专练-线性DP】CF1067A (1900)

A. Array Without Local Maximums

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <stack>
#include <cstdio>
#include <queue>
#include <set>
#include<sstream>
#include <cstring>
#include <cmath>
#include <bitset>
//#pragma GCC optimize(2);
#define IOS ios::sync_with_stdio(false);
#define mm(a, b) memset(a, b, sizeof(a))
const double PI = acos(-1.0);
typedef long long ll;
const int N = 1e5+5;
const int M = N*2;
const double eps =1e-8;
const ll mod =  998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double maxd = -1e9;
const int maxn = 500;
using namespace std;
typedef pair<string,int> PII;
//暴力时间复杂度是n*200*200,边转移边计算前缀和后缀,时间复杂度是n*200
//序列型动态规划,根据题意转移状态就行
//讨论当前点,根据题意推之前点,往前找关系才能写出地推式
//ai-1<ai 0; = 1; > 2;
ll f[N][205][3]; int a[N];
int main(){
    int n;
    cin>>n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    if(a[1] != -1){
        f[1][a[1]][0] = 1;
    }
    else{
        for(int i = 1;i <= 200;i ++){
            f[1][i][0] = 1;
        }
    }
    for(int i = 2;i <= n;i ++){
        ll sum = 0;
        for(int j = 1; j <= 200; j++){
            if(a[i] == -1 || j == a[i]) f[i][j][0] = sum;
            sum += f[i-1][j][0] + f[i-1][j][1] + f[i-1][j][2]; sum%=mod;
        }
        for(int j = 1; j <= 200; j++){
            if(a[i] == -1 || j == a[i])
            f[i][j][1] = f[i-1][j][0] + f[i-1][j][1] + f[i-1][j][2]; sum%=mod;
        }
        sum = 0;
        for(int j = 200; j >=1; j--){
            if(a[i] == -1 || j == a[i]) f[i][j][2] = sum;
            sum += f[i-1][j][1] + f[i-1][j][2]; sum %= mod;
        }
    }
    ll ans = 0;
    for( int i = 1; i <= 200; ++ i){
        ans = (ans + f[n][i][1] + f[n][i][2]) % mod;
    }
    cout << ans <<endl;
    return 0;
}
posted @ 2021-09-15 17:10  qingyanng  阅读(33)  评论(0编辑  收藏  举报