【動態規劃專練-線性DP】CF189A (1300)
阿新 • • 發佈:2021-09-15
線性,計數,計算前後綴優化
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; }