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