欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CodeForces - 1067A Array Without Local Maximums

程序员文章站 2022-05-21 12:10:37
...

题目来源:http://codeforces.com/problemset/problem/1067/A

题意:给你一个序列,序列中的-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]有关,这样第一维可以用滚动数组优化掉。

代码:

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

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

ll pow_mod(ll a, ll b, ll mod) {
    ll ans = 1;
    while (b) {
        if (b & 1)ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return ans % mod;
}

bool is_prime(ll n) {
    if (n == 1 || n == 2)return 1;
    for (int i = 2; i <= sqrt(n); ++i)
        if (n % i == 0)return 0;
    return 1;
}

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

 

相关标签: dp