Codeforces 2195C 题解:Dice Roll Sequence(线性 DP)
题目链接:https://codeforces.com/contest/2195/problem/C
题意重述
给一个长度为 n 的序列 a(每个值在 1..6)。
相邻两项必须满足:
- 不能相等
- 不能互为对面(即
x + y != 7)
一次操作可以把任意位置改成 1..6 中任意值。
问最少改多少次,才能让整个序列合法。
思路
把“改值次数最少”做成位置 DP。
设 dp[i][v] 表示:
- 前
i个位置(0..i)已经处理完 - 第
i个位置最终取值是v - 所需最少修改次数
转移:
如果 u -> v 合法(u != v 且 u + v != 7),则
dp[i][v] = min(dp[i][v], dp[i-1][u] + (a[i] != v))
初始:
dp[0][v] = (a[0] != v)
答案:
min(dp[n-1][1..6])
因为状态只有 6 个,复杂度很小:
- 时间复杂度
O(n * 6 * 6) - 空间复杂度
O(6)(滚动数组)
C++17 代码
1 |
|
样例解释
1 4 2本来就满足条件,答案0。3 4 6 3中4和6互为对面,改一次即可,答案1。
易错点
- 合法条件是同时满足:
u != v且u + v != 7。 - 改值可以改成任意
1..6,不是只能在原值附近调整。 n=1时没有相邻限制,答案始终是0(DP 也会自然得到这个结果)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 David's Blog!
评论