Codeforces Round 612 (Div. 2) C. Garland——DP

💡 原文中文,约2300字,阅读约需6分钟。
📝

内容提要

在Codeforces第612轮比赛中,C题目涉及动态规划。给定一个包含未知数(0)的序列,需要补全使得相邻数值的奇偶性相反的数量最少。通过定义DP数组并进行状态转移,最终输出最小的奇偶性相反数量。

🔎

延伸解读

贪心为何在此题失效

文章提到作者最初尝试贪心,但卡在第十二个样例。这说明局部最优选择无法保证全局相邻奇偶性相反次数最少,因为每个未知位置的填充会影响后续奇偶性匹配,存在后效性。动态规划通过记录已用奇数个数和当前位置奇偶性,能系统考虑所有可能,避免贪心短视。

DP状态设计的核心思路

代码定义dp[i][j][0/1]表示处理到第i+1个位置、共放置j个奇数、且该位置为偶/奇数时的最小相反次数。转移时根据当前位置是否已固定或为0,分别从上一位置奇偶性推导,若奇偶性变化则代价加1。这种设计将奇偶性序列的连续性约束转化为状态转移,清晰且易于实现。

实现中的关键细节

初始化时,若第一个位置为0,则dp[0][1][1]和dp[0][0][0]置0;若已给定数值,则根据其奇偶性设置对应状态。循环中j的上限取min(i+1, (n+1)/2),确保奇数个数不超过总数一半。最终答案取dp[n-1][(n+1)/2][0]和[1]的较小值,保证恰好使用所有奇数。

❓

Q&A

Codeforces第612轮比赛的C题目主要涉及什么内容?

C题目主要涉及动态规划,要求补全一个包含未知数的序列,使得相邻数值的奇偶性相反的数量最少。

如何定义动态规划的DP数组?

DP数组定义为dp[i][j][0/1],表示第i+1个位置放了偶数或奇数,且到第i+1处总共放了j个奇数。

相邻数值的奇偶性相反是什么意思?

相邻数值的奇偶性相反是指两个相邻的数值中,一个为奇数,另一个为偶数。

状态转移方程是如何构建的?

状态转移方程为:dp[i][j][1] = min(dp[i - 1][j - 1][0] + 1, dp[i - 1][j - 1][1]),dp[i][j][0] = min(dp[i - 1][j][1] + 1, dp[i - 1][j][0])。

如何处理序列中的未知数(0)?

根据位置的数值是否为0,决定需要填充的奇数或偶数,如果为0则两个都需要填充。

最终输出的结果是什么?

最终输出的是最小的奇偶性相反数量。

🏷️

标签

➡️

继续阅读