C++ / ACM 自学笔记 · v5.0

(八) 用不变量和反例检查推导

循环不变量是循环开始或结束时始终成立的关系。它帮助我们检查“为什么当前步骤不会破坏已经得到的信息”。

  • 累计和:处理完前 i 个元素后,累计量等于这 i 个元素的和。
  • 连续分组:已完成的组与当前组覆盖了已经读到的全部任务,组内和都没有超过候选上限。
  • 原地去重:写位置之前恰好保存已读元素中的不同值,后面的位置仍可用于继续读写。
  • 检查所有元素:处理完一个前缀后,记录的真假值表示这个前缀是否每项都满足要求。

除了运行样例,还可以给自己的判断找反例。下面把几种看似合理的说法代入小数据,看看计算结果怎样:

要检查的结论 应主动尝试
“偶数一定能分成两个正偶数” 2
“凑钱先拿最大面值一定最优” 面值 [1,3,4],金额 6
“两数之和可以两次使用同一个下标” 只有一个元素 [3],目标 6
“删掉负数仍能得到最大连续区间” [5,-4,5]
“统计下标对时,同值只保留一项” [1,1,5,5],目标和 6

可以把推导整理成四句话:我维护什么状态;这一步为什么合法;为什么不会漏解;什么时候结束并得到答案。 下面继续把反例、证明和实现步骤放到同一道题里,逐项检查这些关系。

练习: 洛谷 P1046 — 陶陶摘苹果、洛谷 P5717 — 三角形分类、洛谷 P1085 — 不高兴的津津。

查阅笔记正文与全部题解 · Ctrl / ⌘ K