1. 程式人生 > >1067A Array Without Local Maximums

1067A Array Without Local Maximums

題意:給你一個序列,序列中的-1可以是[1,200]中的任意數,問該數列有多少種情況滿足任意a[i]<=max(a[i-1],a[i+1])。

思路:dp。首先定義狀態f[i][j][k]表示前i個數,第i個數是j的方案數,其中k=0表示a[i]==a[i-1],k=1表示a[i]<a[i-1]。k=2表示a[i]>a[i-1]。轉移的時候如果a[i]是-1就從1到200列舉,否則只更新f[i][a[i]]。

但這樣陣列為1e5*200*3=6e7。陣列開不下。考慮到f[i]只和f[i-1]有關,這樣第一維可以用滾動陣列優化掉。

更新f[i]的時候需要分類討論,其中,a[i]=a[i-1]=-1的情況需要用到字首和優化。

程式碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>

#define ll long long
#define ull unsigned long long
#define BUG cout<<"*************************\n"
using namespace std;

const ll mod = 998244353;
const int maxn = 4e5 + 10;
const int maxm = 1e6 + 10000;
const double eps = 1e-8;

int n, a[maxn];
ll up_sum[maxn][3], down_sum[maxn][3];
ll f[2][211][3];

int main() {
    /*ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);*/
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    if (a[1] == -1) {
        for (int i = 1; i <= 200; ++i) {
            f[1][i][2] = 1;
        }
    } else {
        f[1][a[1]][2] = 1;
    }
    // 1 a[i]<a[i-1]
    // 2 a[i]>a[i-1]
    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= 200; ++j)
            f[i & 1][j][0] = f[i & 1][j][1] = f[i & 1][j][2] = 0;
        if (a[i] == -1) {
            if (a[i - 1] == -1) {
                for (int j = 1; j <= 200; ++j) {
                    (up_sum[j][0] = up_sum[j - 1][0] + f[1 - (i & 1)][j][0]) % mod;
                    (up_sum[j][1] = up_sum[j - 1][1] + f[1 - (i & 1)][j][1]) % mod;
                    (up_sum[j][2] = up_sum[j - 1][2] + f[1 - (i & 1)][j][2]) % mod;
                }
                for (int j = 200; j >= 1; --j) {
                    (down_sum[j][0] = down_sum[j + 1][0] + f[1 - (i & 1)][j][0]) % mod;
                    (down_sum[j][1] = down_sum[j + 1][1] + f[1 - (i & 1)][j][1]) % mod;
                    (down_sum[j][2] = down_sum[j + 1][2] + f[1 - (i & 1)][j][2]) % mod;
                }
                for (int j = 1; j <= 200; ++j) {
                    f[i & 1][j][0] = (f[1 - (i & 1)][j][0] + f[1 - (i & 1)][j][1] + f[1 - (i & 1)][j][2]) % mod;
                    f[i & 1][j][1] = (down_sum[j + 1][0] + down_sum[j + 1][1]) % mod;
                    f[i & 1][j][2] = (up_sum[j - 1][0] + up_sum[j - 1][1] + up_sum[j - 1][2]) % mod;
                }
            } else {
                for (int j = 1; j < a[i - 1]; ++j) {
                    f[i & 1][j][1] = (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1]) % mod;
                }
                f[i & 1][a[i - 1]][0] =
                        (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1] + f[1 - (i & 1)][a[i - 1]][2]) % mod;
                for (int j = a[i - 1] + 1; j <= 200; ++j) {
                    f[i & 1][j][2] = (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1] +
                                      f[1 - (i & 1)][a[i - 1]][2]) % mod;
                }
            }
        } else {
            if (a[i - 1] == -1) {
                for (int j = 1; j < a[i]; ++j) {
                    f[i & 1][a[i]][2] += f[1 - (i & 1)][j][0] + f[1 - (i & 1)][j][1] + f[1 - (i & 1)][j][2];
                    f[i & 1][a[i]][2] %= mod;
                }
                f[i & 1][a[i]][0] = (f[1 - (i & 1)][a[i]][0] + f[1 - (i & 1)][a[i]][1] + f[1 - (i & 1)][a[i]][2]) % mod;
                for (int j = a[i] + 1; j <= 200; ++j) {
                    f[i & 1][a[i]][1] += f[1 - (i & 1)][j][0] + f[1 - (i & 1)][j][1];
                    f[i & 1][a[i]][1] %= mod;
                }
            } else {
                if (a[i] > a[i - 1]) {
                    f[i & 1][a[i]][2] =
                            (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1] + f[1 - (i & 1)][a[i - 1]][2]) %
                            mod;
                } else if (a[i] == a[i - 1]) {
                    f[i & 1][a[i]][0] =
                            (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1] + f[1 - (i & 1)][a[i - 1]][2]) %
                            mod;
                } else {
                    f[i & 1][a[i]][1] = (f[1 - (i & 1)][a[i - 1]][0] + f[1 - (i & 1)][a[i - 1]][1]) % mod;
                }
            }
        }
    }
    ll ans = 0;
    for (int i = 1; i <= 200; ++i) {
        ans += f[n & 1][i][0] + f[n & 1][i][1];
        ans %= mod;
    }
    cout << ans << endl;
    return 0;
}