CPH-第六章 贪心

贪心算法在每一步都做出当前看起来最优的局部最优选择,并因此得到全局的最优选择。

6.1 硬币问题(Coin Problem)

给定一组硬币面额和一个目标金额,要求用最少数量的硬币凑出该金额。

  • 一个直观的贪心策略是:每次都选不超过剩余金额的最大面额硬币,直到凑满为止。

    • 这个策略并非普遍正确。以欧元硬币为例,贪心法恰好能给出最优解;但在一般的面额系统下,贪心可能失败。
  • 核心启示:贪心策略的有效性依赖于问题结构,不能仅凭直觉认定其正确。

6.2 调度(Scheduling)

给定 \(n\) 个事件,每个事件有开始时间和结束时间,要求选出尽可能多的互不重叠事件。

  • 考虑三种贪心策略,只有第三种被证明是正确的。
策略 结果 反例直觉
选最短的事件 ✕ 一个短事件可能“卡”在两个长事件之间,导致只能选 1 个,而最优解可以选 2 个
选开始最早的事件 ✕ 一个开始很早但结束很晚的事件会独占全部时间,排除了后续多个事件的可能
选结束最早的事件 ✓ 结束越早,留给后续事件的选择空间至少不会更小
  • 正确性论证采用交换论证:如果最优解没有选择结束最早的那个事件,把它替换成结束最早的事件后,后续可选事件的数量不会减少,因此解不会变差。

6.3 任务与截止日期(Tasks and Deadlines)

给定 \(n\) 个任务,每个任务有持续时间和截止时间。完成一个任务获得 \(d - x\) 分,其中 \(d\) 是截止时间,\(x\) 是实际完成时刻。目标是最大化总分。

  • 一个出人意料的结论是:最优顺序完全不依赖截止时间,只需按持续时间从短到长排序即可。

  • 正确性同样来自交换论证:如果相邻两个任务中,前一个的持续时间长于后一个,交换它们会使总分严格增加。因此,在最优解中,任意相邻任务都必须满足“短任务在前”,从而整个序列按持续时间升序排列即为最优。

6.4 最小化和(Minimizing Sums)

给定 \(n\) 个数 \(a_1, a_2, \ldots, a_n\),要求找一个值 \(x\),使某个和式最小。

  • 这一节展示了贪心思想在连续优化场景中的一种形态:最优解并不出现在端点或均值处

  • \(c = 1\),\(x\) 取在中位数

  • \(c = 2\),\(x\) 取平均值

6.5 数据压缩(Data Compression)

前缀码约束

  • 任何一个码字都不能是另一个码字的前缀,否则解码时会产生歧义。满足这一约束的编码对应一棵二叉树:字符位于叶子,从根到叶的路径(左 0 右 1)就是码字。

哈夫曼算法

  • 哈夫曼算法的贪心选择——每次都合并当前最轻的两个节点——可被证明能产生加权路径长度最小的二叉树,即最优前缀码。
  • 算法流程:
    • 为每个字符建立一个节点,权重为其出现频率。
    • 反复取出权重最小的两个节点,合并为一个新节点,权重为两者之和。
    • 重复直到只剩一个根节点。
    • 以字符串 AABACDACA 为例:A 的频率为 5,B、C、D 各为 1、2、1。合并过程最终得到码字 A→0、C→10、B→110、D→111,压缩后为 15 bit,优于等长编码的 18 bit。
posted @ 2026-10-29 15:29  LifeLotus  阅读(8)  评论(0)    收藏  举报