1. 程式人生 > 其它 >【動態規劃專練-線性DP】CF189A (1300)

【動態規劃專練-線性DP】CF189A (1300)

線性,計數,計算前後綴優化

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