CF1032C Playing Piano
题意简述
给定长度为
-
- 若
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 \neq b_i + 1 。
题目分析
构造方案如果不能以下想出来的话可以先考虑判断合法性。每一位
设
接下来考虑如何记录方案。只需要将每次选择的数据记录到 DP 数组里面就行。
改设
状态转移方程:
最后 DFS 从后往前搜一遍统计路径即可。
时间复杂度
AC Code
CI N = 2e5 + 5;
int n, a[N], dp[N][6];
std::vector<int> v;
void dfs(int step, int finger) {
if(step == 1) {
std::reverse(all(v));
for(int i : v) printk(i);
exit(0);
}
rep(i, 1, 5) if((dp[step][finger] >> i - 1) & 1) v.p_b(i), dfs(step - 1, i), v.pop_back();
}
signed main() {
n = read();
arrin(a, n);
rep(i, 1, 5) dp[1][i] = 1;
rep(i, 2, n) rep(j, 1, 5)
if(a[i] < a[i - 1]) rep(k, j + 1, 5) dp[i][j] |= !!dp[i - 1][k] << k - 1;
else if(a[i] > a[i - 1]) rep(k, 1, j - 1) dp[i][j] |= !!dp[i - 1][k] << k - 1;
else rep(k, 1, 5) if(k != j) dp[i][j] |= !!dp[i - 1][k] << k - 1;
bool flag = 0;
rep(i, 1, 5) flag |= dp[n][i];
if(!flag) puts("-1"), exit(0);
dp[n + 1][0] = -1;
dfs(n + 1, 0);
return 0;
}