CF1032C Playing Piano

大意:
给出一个长度为n的序列a,现在要求构造一个序列b,满足:
(a_i<a_{i+1})(b_i<b_{i+1})
(a_i>a_{i+1})(b_i>b_{i+1})
(a_i==a_{i+1})(b_i!=b_{i+1})
且b的元素都在1到5之间
思路:
直接dp,根据前一个的状态能否达到来更新当前的状态,然后保存路径即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int n;
int a[N];
bool dp[N][10];
int pre[N][10];
int res[N];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= 5; i++) dp[1][i] = true;
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= 5; j++) dp[i][j] = false;
        for (int j = 1; j <= 5; j++) {
            if (!dp[i - 1][j]) continue;
            if (a[i] == a[i - 1]) {
                for (int k = 1; k <= 5; k++) {
                    if (j != k) {
                        dp[i][k] = true;
                        pre[i][k] = j;
                    }
                }
            }
            if (a[i] < a[i - 1]) {
                for (int k = 1; k < j; k++) {
                    dp[i][k] = true;
                    pre[i][k] = j;
                }
            }
            if (a[i] > a[i - 1]) {
                for (int k = j + 1; k <= 5; k++) {
                    dp[i][k] = true;
                    pre[i][k] = j;
                }
            }
        }
    }
    for (int i = 1; i <= 5; i++) {
        if (dp[n][i]) {
            int c = i;
            for (int j = n; j >= 1; j--) {
                res[j] = c;
                c = pre[j][c];
            }
            for (int j = 1; j <= n; j++) cout << res[j] << ' ';
            cout << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14619736.html