交换论证、归约与下界证明

共 19 题
📑 题目列表 19 题
#
★★★

1. 贪心正确性证明的'安全边'框架中以 Kruskal 为例,如何用切割性质(cut property)证明每次选择的边都属于某个最小生成树?

说明贪心正确性证明的"安全边"框架,并以 Kruskal 算法为例,用切割性质(cut property)证明每次选择的边都属于某个最小生成树?

  • 安全边(safe edge)的概念
  • 切割性质(cut property)的叙述
  • 用切割性质证明 Kruskal 边安全

安全边框架:若已构造一个不完整的最小生成树 A(A 是某个 MST 的子集),则"安全边"是一条加入 A 后仍保持 A 是某个 MST 子集的边。若每次选择安全边,则最终 A 扩展为 MST。切割性质(cut property):设 A 是某个最小生成树的子集,对任意切割 (S, V−S),若 A 不包含跨越该切割的边,且 e 是跨越该切割的最小权边,则 e 是安全边。Kruskal 的证明:算法按权值从小到大遍历边,检查是否形成环。设当前处理的边 e=(u,v),若 e 的端点分属不同连通分量,则 e 不构成环。考虑切割:把 u 所在连通分量记为 S,则 (S, V−S) 是一个切割,A 中无跨越它的边(因为 u、v 分属不同分量,A 中无连接两者的边)。e 是跨越该切割的最小权边吗?因为 Kruskal 按权值升序处理,之前加入的边权都 ≤ w(e),且 e 是当前最小的安全候选,故 e 是跨越该切割的最小权边。由切割性质,e 是安全边,加入后 A 仍是某个 MST 的子集。归纳得最终 A 是 MST。

安全边框架把贪心正确性归约为"每次选择都是安全边"。切割性质提供了一种通用的安全边判定:只要存在一个不含 A 中边的切割,且所选边是该切割最小权边,它就是安全的。Kruskal 用"连通分量"构造切割,用"升序处理"保证最小权,从而每次选择都满足切割性质。

// Kruskal 最小生成树(并查集 + 按权排序)
class Edge implements Comparable<Edge> { int u, v, w; public int compareTo(Edge o){return w-o.w;} }
int kruskal(int n, Edge[] edges) {
    Arrays.sort(edges);
    DSU dsu = new DSU(n);
    int total = 0;
    for (Edge e : edges) {
        if (dsu.find(e.u) != dsu.find(e.v)) { // 不构成环:e 是安全边
            dsu.union(e.u, e.v);
            total += e.w;
        }
    }
    return total;
}
#
★★★

2. 区间贪心问题的变体中区间选点、区间覆盖与最大不相交区间的贪心策略分别是什么,为什么排序键不同?

说明区间选点、区间覆盖与最大不相交区间三种区间贪心问题的贪心策略分别是什么,并解释为什么排序键不同?

  • 三种区间贪心的策略
  • 各自的排序键
  • 排序键差异的原因

三种变体及策略:

  1. 最大不相交区间(活动选择):选尽可能多的互不重叠区间。贪心策略:按右端点升序排序,每次选结束最早且与已选不冲突的区间。从右端点排序,因为"结束早"给后续留出最多空间。
  2. 区间选点:用最少的点覆盖所有区间(每个区间至少含一个点)。贪心策略:也按右端点升序排序,每遇到当前点未覆盖的区间,就在其右端点处放一个点。排序键是右端点,因为点放在右端点能覆盖所有"右端点≥该点"且尚未覆盖的区间。
  3. 区间覆盖:用最少的区间覆盖给定的目标区间 [L,R]。贪心策略:按左端点升序排序,每次选能覆盖当前起点的、右端点最大的区间,然后推进起点。排序键是左端点,因为要保证覆盖连续性,需从 L 开始一步步推进。 排序键不同是因为目标不同:活动选择/选点希望"每个区间尽量早结束",用右端点;区间覆盖要求"从起点连续推进",用左端点。

三种变体之所以排序键不同,源于贪心决策的"局部最优"定义不同:活动选择与选点以"结束最早"为局部最优(右端点),区间覆盖以"覆盖最远"为局部最优(左端点+右端点最大)。理解贪心选择性质即可推导排序键。

#
★★

3. 拟阵(matroid)与贪心算法中为什么贪心在拟阵上正确,Kruskal 最小生成树与拟阵贪心的一般化关系?

说明拟阵(matroid)与贪心算法:为什么贪心在拟阵上正确,并解释 Kruskal 最小生成树与拟阵贪心的一般化关系?

  • 拟阵的定义(独立集、遗传性、交换性)
  • 拟阵贪心定理
  • 图拟阵与 MST 的关系

拟阵 M=(S, I) 满足:①I 是 S 的子集族(独立集);②遗传性:若 A∈I 且 B⊆A 则 B∈I;③交换性(增广):若 A,B∈I 且 |A|<|B|,则存在 b∈B−A 使 A∪{b}∈I。拟阵贪心定理:对带权元素 S,按权值降序依次加入元素,保持独立集,得到的最大权独立集是全局最优。证明用交换性:若贪心选了 x 而最优选了 y(x 权更大),可交换保持独立性。Kruskal 与拟阵:把图的边集作为 S,独立集定义为"无环的边集"(森林),构成图拟阵(graphic matroid),满足遗传性(森林的子集是森林)与交换性(两森林一大一小,可从小森林移入大森林的边而不成环)。MST 求最小权生成树等价于求最大权独立集(把权取负):Kruskal 按权值升序加边、保持无环,正是拟阵贪心算法对图拟阵的应用。因此 Kruskal 的正确性由拟阵贪心定理保证。

拟阵是"贪心正确"的抽象充分条件:只要结构满足遗传性与交换性,按权贪心就最优。图拟阵满足这两条,故 Kruskal 是拟阵贪心的特例。这解释了为什么贪心在拟阵上普遍正确,而 0-1 背包等不满足交换性的问题贪心会失败。

// 拟阵贪心通用框架(伪代码):按权降序依次考虑元素,保持独立
//   matroidGreedy(加权元素集 E, 独立性判定 oracle):
//     sort E by weight descending;
//     selected = empty;
//     for (e : E) if (selected + {e} is independent) selected.add(e);
//   selected 即最大权独立集;对图拟阵(独立集=森林)等价于 Kruskal 按权升序加边保无环
#
★★

4. 贪心算法的适用性判定中如何判断问题具有贪心选择性质与最优子结构,用 0-1 背包 vs 分数背包说明反例?

说明如何判断问题具有贪心选择性质与最优子结构,并用 0-1 背包与分数背包作为反例说明?

  • 贪心选择性质与最优子结构
  • 分数背包可贪心、0-1 背包不可贪心
  • 反例构造

贪心选择性质:局部最优选择能导致全局最优解,即"先贪心选一步,剩余问题仍可用贪心解决";最优子结构:问题的最优解包含子问题的最优解。判断方法:一般应证明贪心导致的解与某个最优解一致(交换论证),或证明贪心选择性质与最优子结构成立。分数背包:物品可分割,按单位价值(价值/重量)降序贪心即可,因为可不断装入单位价值最高的物品,且最优子结构成立。0-1 背包:物品不可分割,按单位价值贪心会失败。反例:背包容量 50,物品 A(价值 60,重量 10,单位价值 6)、B(价值 100,重量 20,单位价值 5)、C(价值 120,重量 30,单位价值 4)。按单位价值降序贪心先选 A、B,剩余容量 20 装不下 C,总价值 160;而最优解是选 B+C,价值 220,贪心失败。更典型:容量 10,物品1(价值 60,重量 6,单位 10)、物品2(价值 50,重量 5,单位 10)、物品3(价值 50,重量 5,单位 10):贪心选 1 后容量 4 无法再加,价值 60;最优选 2+3 价值 100。故 0-1 背包无贪心选择性质,需动态规划。

分数背包因"可分割"使贪心选择局部最优即全局最优;0-1 背包因"不可分割"使贪心后剩余容量无法利用,破坏贪心选择性质。最优子结构两者都有,但 0-1 背包缺贪心选择性质,故用 DP 而非贪心。

// 分数背包:按单位价值降序贪心(正确)
double fractionalKnapsack(Item[] items, int cap) {
    Arrays.sort(items, (a,b) -> Double.compare(b.value/(double)b.weight, a.value/(double)a.weight));
    double total = 0;
    for (Item it : items) {
        if (cap >= it.weight) { total += it.value; cap -= it.weight; }
        else { total += it.value * (cap / (double) it.weight); break; }
    }
    return total;
}
// 0-1 背包:贪心失败,需 DP
#
★★

5. 交换论证(Exchange Argument)的证明框架中以活动选择、任务调度为例说明贪心正确性?

说明交换论证(Exchange Argument)的证明框架,并以活动选择、任务调度为例说明贪心正确性?

  • 交换论证的三个步骤
  • 活动选择的交换论证
  • 任务调度的交换论证

交换论证框架:证明贪心解不劣于任意最优解,分三步:①取一个最优解 O 和贪心解 G;②若 O 与 G 不同,找到第一个不同的决策,交换 O 中该决策为贪心决策,得到新解 O';③证明 O' 不劣于 O(交换不劣化),且 O' 与 G 更接近,归纳得 G 最优。活动选择:贪心选结束最早的活动。设最优解 O 的第一个活动是 a,贪心选的是 g(结束最早)。若 a≠g,则 g 结束不晚于 a,把 O 中 a 换成 g,后续活动仍不冲突(g 结束更早),O' 不劣于 O,且与贪心解一致;递归证明贪心最优。任务调度:加工时间最短的先做(SPT)使总完成时间最小。交换论证:若最优解中两个相邻任务 i、j 顺序为 i 在 j 前但 p_i>p_j,交换两者,其他任务完成时间不变,i 的任务完成时间减少、j 增加,净变化 = 交换后总完成时间减少(因为 p_i>p_j),故交换不劣化。反复交换得 SPT 顺序最优。

交换论证的核心是"把最优解逐步调整为贪心解而不劣化"。活动选择靠"结束最早不冲突"性质,任务调度靠"短任务先前移减少等待"的相邻交换。两者都证明贪心解与某个最优解一致,从而贪心最优。

#
★★

6. 归约(Reduction)在复杂度证明中的应用中如何证明问题 A 不慢于问题 B(A ≤p B)?

说明归约(Reduction)在复杂度证明中的应用,如何证明问题 A 不慢于问题 B(A ≤p B)?

  • 多项式归约 A ≤p B 的定义
  • 归约的方向与含义
  • 如何构造与验证归约

多项式归约 A ≤p B:存在多项式时间可计算的函数 f,把 A 的任意实例 x 映射为 B 的实例 f(x),且 x 是 A 的 yes 实例当且仅当 f(x) 是 B 的 yes 实例。含义:若 B 可多项式时间求解,则 A 也可(先归约再解 B),故 A 不慢于 B(A 的困难度 ≤ B 的困难度)。这与"解决"方向相反:为证明 A 难,需把已知难问题归约到 A(即 A 是已知难问题的推广)。证明 A ≤p B 的步骤:①描述把 A 实例 x 转为 B 实例 f(x) 的多项式算法;②证明双向保持:x 有解 ⟺ f(x) 有解(yes↔yes);③验证 f 多项式时间。若已知 B∈P,则 A∈P(A 不慢于 B);若已知 A 是 NP-hard,则 B 也是 NP-hard(B 至少和 A 一样难)。

归约是复杂度理论的"难易程度比较器"。A ≤p B 意味着"解决 B 的能力足以解决 A"。判断归约方向时记住:为证明"新问题 B 难",用已知难问题 A 归约到 B(A ≤p B);为证明"新问题 A 容易",用 A 归约到已知易问题 B(A ≤p B)。

#
★★

7. 基于决策树证明比较排序 Ω(n log n) 下界的完整推导?

给出基于决策树证明比较排序 Ω(n log n) 下界的完整推导?

  • 决策树模型的建立
  • 叶子数 ≥ n! 的论证
  • 树高 ≥ log2(n!) = Ω(n log n)

比较排序的决策树:每个排序算法对固定输入规模 n 的决策过程可用一棵二叉树表示。内部节点表示一次比较(两元素的比较),左/右分支表示比较结果,叶子表示最终排列。合法输入有 n! 种排列,算法必须区分所有 n! 种排列,故叶子数至少 n!。一棵高度为 h 的二叉树最多有 2^h 个叶子,故 2^h ≥ n!,即 h ≥ log2(n!)。用 Stirling:log2(n!) = n log2 n − n log2 e + O(log n) = Ω(n log n)。因此任何比较排序在最坏情况下至少需要 n log n 次比较,即比较排序下界为 Ω(n log n)。推导完整链条:决策树高度 h ≥ log2(叶子数) ≥ log2(n!) = Ω(n log n) = 最坏情况比较次数下界。

决策树方法把"算法比较次数"映射为"决策树高度",把"必须区分 n! 种排列"映射为"叶子数 ≥ n!"。二叉树高度与叶子数的关系 2^h≥L 给出 h≥log2(L),结合 Stirling 得 Ω(n log n)。这是"信息论下界"在比较排序的应用。

#
★★

8. 证明最小生成树的 Cut Property(切割性质),为什么跨越切割的最小权边必在某个 MST 中?

证明最小生成树的切割性质(Cut Property):为什么跨越某切割的最小权边必在某个最小生成树中?

  • 切割性质的内容
  • 反证法证明
  • 切割性质与安全边的关系

切割性质:对图 G=(V,E) 的任意切割 (S, V−S),若 e 是跨越该切割的最小权边,则 e 属于某个最小生成树(MST)。证明(反证):设 T 是任意 MST,假设 e=(u,v) 不在 T 中。由于 e 跨越切割,而 T 是连通生成树,T 中必有某条边 f 也跨越该切割(否则 T 不连通 S 与 V−S)。把 f 加入 T 会形成环,但用 e 替换 f 得到 T'=T−{f}+{e}。T' 仍是生成树(连通且无环)。因 e 是跨越切割的最小权边,w(e)≤w(f),故 w(T')≤w(T)。由于 T 是 MST,w(T')≥w(T),故 w(T')=w(T),即 T' 也是 MST 且包含 e。注意若 w(e)<w(f) 则 T' 权更小,矛盾于 T 是 MST;若 w(e)=w(f) 则 T' 也是 MST。故跨越切割的最小权边必在某个 MST 中。

切割性质是 MST 领域的核心工具,证明用"替换论证":MST 中必然有某条跨切割的边,用最小权跨切割边替换它不增加总权,故得新 MST。这一性质同时证明了 Kruskal 每次选择的边是安全边。

#
★★

9. CLRS 第 16 章活动选择问题的最优子结构与贪心选择性质?

说明 CLRS 第 16 章活动选择问题的最优子结构与贪心选择性质?

  • 活动选择问题的最优子结构
  • 贪心选择性质(选结束最早)
  • 贪心正确性证明

活动选择问题:给定 n 个活动(开始时间 s_i、结束时间 f_i),选最多互不冲突的活动。最优子结构:设 S_ij 是活动序列中在活动 i 结束后、j 开始前可执行的活动集合,其最优解 A_ij 包含对某个活动 k(在 S_ij 中)的 A_ik 和 A_kj 两个子问题的最优解,即 A_ij = A_ik ∪ {k} ∪ A_kj,且 A_ik、A_kj 各自最优。贪心选择性质:考虑 S_ij 中结束最早的活动 a_m(f_m 最小),则 a_m 属于 S_ij 的某个最优解。证明:设最优解 A_ij 的第一个活动是 a_k,因 a_m 结束最早,f_m≤f_k,把 A_ij 中的 a_k 替换为 a_m,得到不冲突的 A_ij'(a_m 结束更早不影响后续),且 |A_ij'|=|A_ij|,故 A_ij' 也是最优且含 a_m。因此贪心(选结束最早)符合贪心选择性质。结合最优子结构,递归贪心(每次选结束最早且不与已选冲突的活动)得到全局最优。

活动选择同时具备最优子结构与贪心选择性质,是典型的贪心问题。贪心选择性质(结束最早)由"替换论证"证明:结束最早的活动可替换最优解首活动而不劣化。这使 CLRS 用贪心而非 DP 求解。

#

10. 比较排序下界的决策树模型,n! 种可能输出要求决策树高度至少 log2(n!)=Ω(n log n),如何写出严格的树高论证?

说明比较排序下界的决策树模型:为什么 n! 种可能输出要求决策树高度至少 log2(n!)=Ω(n log n),并写出严格的树高论证?

  • 决策树模型与叶子对应输出排列
  • 树高与叶子数的关系
  • 严格的树高论证

决策树模型:对固定 n,比较排序算法对应一棵二叉树,每个内部节点是一次比较,叶子是输出排列。算法必须为每种输入排列产生正确输出,故每个排列对应一个叶子(或至少所有 n! 种排列都要被区分),叶子数 L ≥ n!。树高 h 与叶子数关系:一棵高度为 h 的二叉树最多有 2^h 个叶子(满二叉树),故 2^h ≥ L ≥ n!,即 h ≥ log2(n!)。严格的树高论证:log2(n!) = Σ_{k=1}^n log2 k ≥ n log2 n − n log2 e + O(log n) = Ω(n log n)(用 Stirling 或积分)。因此 h ≥ log2(n!) = Ω(n log n)。由于最坏情况比较次数等于决策树高度(最坏路径),故比较排序最坏情况至少 Ω(n log n) 次比较。

核心是"n! 种排列都得被区分"和"二叉树高度 h 最多 2^h 个叶子"两个事实,结合 Stirling 得 log2(n!)=Ω(n log n)。这是信息论下界:每个比较最多提供 1 位信息,区分 n! 种排列需要 log2(n!) 位。

#

11. 拟阵的秩函数(rank function)为什么满足次模性,次模性在证明拟阵贪心算法最优性中起什么作用?

说明拟阵的秩函数(rank function)为什么满足次模性,以及次模性在证明拟阵贪心算法最优性中起的作用?

  • 秩函数的定义
  • 次模性的定义与证明
  • 次模性在贪心最优性证明中的作用

拟阵 M=(S,I) 的秩函数 r(A)=max{|I| : I⊆A, I∈I},即 A 中最大独立集的大小。秩函数满足次模性:对任意 A,B⊆S,r(A)+r(B) ≥ r(A∪B)+r(A∩B)。证明思路:逐元素递推,对 A∩B 的每个元素 x 依次加入,用交换性证 r(A∪{x})−r(A) ≤ 1 且 r(A∪{x})−r(A) ≤ r(B∪{x})−r(B)(当 B⊆A 时),其中 r(A∪{x})−r(A) 是"把 x 加入 A 的秩增量",要么 0 要么 1。由此推出 r(A∪B)−r(A) ≤ r(B)−r(A∩B),即次模不等式。次模性在拟阵贪心最优性证明中的作用:秩的"边际增益递减"性质(次模性)刻画了贪心"每次选最大权/最大边际增益元素"的合理性。对拟阵,次模性配合贪心每步选最大边际增益,证明贪心得到的最大权独立集是全局最优。

秩的次模性本质是"边际增益递减":把固定元素加入更大的集合所得增益 ≤ 加入更小集合。拟阵贪心算法的最优性证明依赖此性质来保证"贪心选择的元素序列在全局上最优"。次模性是拟阵贪心正确性的核心代数工具。

#

12. 归约(reduction)的构造与验证中从 3-SAT 归约到 CLIQUE/SUBSET-SUM 时,如何保证'yes 实例 ↔ yes 实例'双向保持?

说明从 3-SAT 归约到 CLIQUE/SUBSET-SUM 时如何构造归约,并保证'yes 实例 ↔ yes 实例'双向保持?

  • 归约的构造方法
  • 双向保持的验证
  • 3-SAT→CLIQUE 与 3-SAT→SUBSET-SUM 的构造

归约构造需把 3-SAT 实例转成目标问题实例,并保证双向保持。3-SAT→CLIQUE:给定 3-CNF 公式,对每个子句 C_i 的三个文字各建一个节点,共 3m 个节点(m 为子句数);两节点连边当且仅当它们来自不同子句且不是互补文字(如 x 与 ¬x)。设 k=m。验证:若公式可满足,取每个子句中为真的文字对应节点,构成大小为 m 的团(任意两个不同子句的真文字满足赋值、不互补,故两两相连);反之,若存在大小为 m 的团,因团中节点来自不同子句(跨子句才连边),且无互补文字,可给每个子句选一个团中文字设真,得一致赋值,公式可满足。故 yes↔yes。3-SAT→SUBSET-SUM:为每个变量 x 和 ¬x 各建一个十进制"数字"(权重),为每个子句建两个"进位修正"数字,设计数字使子集和等于目标值当且仅当存在满足赋值。验证:若子集和可组成目标值,每位数字对应变量选真/假,且子句覆盖成立;反向同理。双向保持通过"构造上的精确对应"保证。

归约验证的核心是双向保持:yes 方向(可满足→存在团/子集和)与 no 方向(存在团/子集和→可满足)都要证明。构造时通常围绕"变量赋值"与"子句覆盖"建立一一对应,使目标问题的解编码了原问题的满足赋值。

#

13. 信息论与对抗下界的结合中为什么找中位数的下界不能仅靠信息论得出,需要更精细的对手论证(约 2n 次比较)?

说明为什么找中位数的下界不能仅靠信息论得出,需要更精细的对手论证(约 2n 次比较)?

  • 信息论下界的局限
  • 对手论证(adversary argument)的思想
  • 中位数下界 ~2n 次比较

信息论下界:找中位数需要区分 n 个可能的中位数位置,log2(n) 位信息,故下界仅 log2 n 次比较,远小于实际需要,信息论下界太松。因为信息论只考虑"需要区分多少种输出",不考虑比较之间的结构性约束(如要确定中位数需先确定哪些元素小/大)。对手论证(adversary):设计一个"对手"在回答比较时总给出最不利的答案,迫使算法积累足够信息。找中位数需确定中位数,其上下各有约 n/2 个元素。对手论证可证明找中位数至少需要约 2n 次比较:证明思路是每个元素必须至少参与一次比较,且要证明中位数两侧的 n/2−1 个元素分别"大于"或"小于"中位数,需要足够的多对比较。具体展开:中位数 m 需满足有 n/2−1 个元素 < m 和 n/2−1 个元素 > m。对手论证显示,即便把找最大与最小合并,也需约 2n 次比较才能确定中位数(例如用"配对"方法构造下界)。因此信息论不足,需对手论证给出更紧的 ~2n 下界。

信息论下界只依赖"输出数量",忽略算法结构;对手论证通过"最坏响应"直接刻画任何算法必须做的最少"信息收集"操作。中位数问题的关键信息是"元素间的大小关系格局",仅 log n 位不够,需约 2n 次比较来建立"以中位数为界的上下两部分"。

#

14. 拟阵与匹配的界限中二分图匹配不是拟阵(匹配并集不满足交换性),这如何解释匈牙利算法的复杂性?

说明为什么二分图匹配不是拟阵(匹配并集不满足交换性),并解释这如何导致匈牙利算法的复杂性?

  • 匹配的独立集定义与交换性不足
  • 为什么匹配并集不满足交换性
  • 匈牙利算法的复杂性来源

匹配的独立集定义为"两两不相交的边集"(无公共端点)。匹配族不满足拟阵的交换性:设 A、B 是两个匹配,|A|<|B|,交换性要求存在一条边 b∈B−A 使 A∪{b} 仍是匹配。但 B 中可能没有一条边能独立加入 A 而不与 A 冲突。反例:A={(u1,v1)},B={(u1,v2),(u2,v1)},|A|=1<|B|=2,但 B 中任一条边加入 A 都会与 A 共享端点(u1 或 v1),不构成匹配。故匹配并集不满足交换性,匹配不是拟阵。这正是贪心在匹配上失效的原因,也解释了为什么最大匹配需要"增广路径"算法(匈牙利算法)而非贪心。匈牙利算法通过反复寻找"增广路径"(交替非匹配/匹配边)来扩大匹配,每次增广 O(E) 或 O(V),共需 O(V) 次增广,故总复杂度 O(V·E)(朴素)或 O(V^(1/2)·E)(Hopcroft-Karp)。因为匹配无拟阵性质,无法用贪心一步到位,必须用增广路径这一"可交换性缺失"的替代机制。

匹配不是拟阵的根因是"交换性"失败:并集可能强制共享端点。这使贪心不适用,匈牙利算法用增广路径实现"不破坏已匹配的扩展"。拟阵成立则贪心 O(E log E) 即可,匹配需要增广路径的 O(V·E) 级别,正体现了拟阵性质缺失带来的复杂性。

#

15. Huffman 编码最优性的交换论证中两个最小频率的字符一定可以位于编码树最深的两片叶子,如何归纳证明?

说明 Huffman 编码最优性的交换论证:为什么两个最小频率的字符一定可以位于编码树最深的两片叶子,并给出归纳证明?

  • Huffman 编码的最优性
  • 最小频率字符在最深叶子的论证
  • 归纳证明

Huffman 编码的目标是最小化 Σ f_i·d_i(f_i 频率,d_i 编码深度)。交换论证证明:设最优前缀码树 T,两个最小频率字符 a、b。若 a、b 不在最深叶子,可交换它们到最深兄弟叶子而不增加总代价。具体:取最深的两片兄弟叶子 x、y(深度最大),因为 f_a、f_b 最小,交换 a 与 x、b 与 y 后,T 中 a、b 深度增大(代价增加极小),而 x、y 深度减小(代价减少较多),总代价不增(因 f_a+f_b ≤ f_x+f_y,且深度交换后净变化 ≤ 0)。故存在最优树中 a、b 位于最深叶子且为兄弟。归纳证明:把 a、b 合并为一个节点(频率 f_a+f_b),得到规模 n−1 的问题。若 n−1 问题的最优树已知,把 a、b 作为该节点的两个孩子,得到原问题的最优树。归纳起点(n=2)显然。Huffman 算法正是每次合并两个最小频率,正是这个归纳的构造性实现。

交换论证保证了"最小频率放最深"不劣化,归纳则说明"合并最小频率"这一贪心步骤是最优结构。Huffman 算法把这两个结果结合,每次合并最小频率字符,保证最优前缀码。

#

16. 贪心正确性的交换论证中以任务调度/区间覆盖为例展示"交换不劣化"证明?

以任务调度/区间覆盖为例,展示贪心正确性证明中"交换不劣化"的交换论证?

  • 交换论证的"交换不劣化"步骤
  • 任务调度的相邻交换证明
  • 区间覆盖的交换证明

任务调度(单机最小化总完成时间):按加工时间升序(SPT)。交换论证:设最优解中相邻任务 i、j 顺序 i 在 j 前但 p_i>p_j。交换 i、j 后,i、j 之前和之后的任务完成时间不变;i 的完成时间减少 p_j,j 的完成时间增加 p_i,但 i 的减少发生在更早时间、j 的增加发生在更晚时间,对"总加权完成时间"或"平均完成时间"减少(短任务提前使更多任务受益)。因此交换后不劣化,反复交换得 SPT 顺序最优。区间覆盖:证明贪心(每次选覆盖当前起点的最右区间)最优。交换论证:设最优解 O 的第一个区间覆盖起点 L,贪心选的 G 是覆盖 L 且右端点最大者。G 的右端点 ≥ O 首区间的右端点(G 覆盖最远),把 O 中首区间换成 G,后续区间仍可覆盖到 G 右端点之后,甚至更优,交换不劣化。归纳得贪心最优。

"交换不劣化"是交换论证的关键步骤:证明把最优解中某个决策换成贪心决策后,解的代价不增。任务调度用"短任务提前"减少总完成时间,区间覆盖用"贪心选覆盖最远"保证后续覆盖不受损。两者都通过相邻/首部交换维持最优性。

#

17. 对手论证(adversary argument)如何证明找最小值需要至少 n-1 次比较,与决策树方法的区别?

说明对手论证(adversary argument)如何证明找最小值需要至少 n−1 次比较,并说明其与决策树方法的区别?

  • 对手论证的思想
  • 找最小值 n−1 下界证明
  • 与决策树方法的区别

对手论证:设计一个"对手",在算法询问比较时给出最不利的答案,使算法无论怎么比较都得不出结论,从而迫使算法至少做够多次比较。找最小值:证明至少 n−1 次比较,因为每个元素(除最小值外)都必须"输"过一次才能被排除。若某个元素从未输过,则它可能是最小值,算法无法确定答案。对手论证赋予每个元素一个"状态":未输过(可能最小)或已输过。每次比较至少让一个元素从"未输"变为"已输"(对手让输的一方是唯一确定更大者)。最终只剩一个元素未输,即最小值。每次比较至多淘汰一个元素,要淘汰 n−1 个元素需至少 n−1 次比较,故下界 n−1。与决策树方法的区别:决策树方法基于"输出数量/状态数量"(信息论),关注叶子数量;对手论证基于"对抗性信息收集",直接跟踪算法必须建立的最小信息量(如"有多少元素输过")。对手论证更精细,能给出决策树方法给不出的紧下界(如中位数 ~2n、最大最小 3n/2−2)。

对手论证是"对抗性"下界:假设对手总是给出让算法最困惑的回答,迫使算法积累足够信息。找最小值的关键信息是"每个非最小元素必须证明自己不是最小(输过)",n−1 次比较是必要信息量。这比决策树"只数输出"更贴合代数/比较结构。

#

18. 信息论下界中需要 log2(n!) 约等于 n log n 个比较位才能区分 n! 种排列,决策树叶数如何推出 Ω(n log n)?

说明信息论下界:为什么需要 log2(n!) 约等于 n log n 个比较位才能区分 n! 种排列,决策树叶数如何推出 Ω(n log n)?

  • 信息论下界的基本思想
  • 每位比较 = 1 位信息
  • 从叶数推出树高

信息论下界基本思想:每个比较输出只能给出 1 位信息(左/右),要区分 n! 种可能排列,需要至少 log2(n!) 位信息,即至少 log2(n!) 次比较。n! 种排列对应 n! 个不同的输出,若少于 log2(n!) 次比较(即树高 < log2(n!)),则至多 2^h 种输出路径,无法容纳 n! 种排列,必有两种排列产生相同输出,算法无法区分。决策树推导:决策树叶子数 ≥ n!(每个排列对应一个叶子),树高 h 满足 2^h ≥ 叶子数,故 h ≥ log2(n!) = n log2 n − n log2 e + O(log n) = Ω(n log n)。因此任何比较排序最坏需 Ω(n log n) 次比较。log2(n!) ≈ n log n 是因为 Stirling:log2(n!) = n log2 n − O(n),主导项是 n log n。

信息论下界的核心是"信息量度量":区分 N 种可能至少需要 log2 N 位信息,每个比较提供 1 位。决策树把"比较次数"与"树高"、把"排列数"与"叶子数"对应起来,从而用 log2(n!)=Ω(n log n) 封闭下界。

#

19. 归约的传递性中如何用已知困难问题归约证明新问题也困难?

说明归约的传递性:如何用已知困难问题归约证明新问题也困难?

  • 归约的传递性:A≤p B 且 B≤p C 则 A≤p C
  • 用已知难问题归约到新问题证明新问题难
  • 方向与逻辑

归约的传递性:若 A ≤p B 且 B ≤p C,则 A ≤p C(先把 A 实例归约到 B 实例,再把 B 实例归约到 C 实例,两步都是多项式时间,复合仍是多项式时间,且 yes 实例双向保持)。应用:为证明新问题 P 是 NP-hard,需找一个已知 NP-hard 问题 Q,构造 Q ≤p P。若 P 多项式可解,则 Q 也可解(由传递性),但已知 Q 是 NP-hard(除非 P=NP),故 P 至少和 Q 一样难,即 P 是 NP-hard。归纳地,可用已知 NP-hard 问题链(如 SAT→3-SAT→CLIQUE→...)逐级归约,证明一系列新问题困难。若进一步证明 P∈NP,则 P 是 NP-complete。归约方向关键:为证明"新问题难",把已知难问题归约到新问题(Q ≤p P),不是反过来。

归约传递性使"难度"可以沿链传导:一旦某问题被证明 NP-hard,它可归约到的新问题也 NP-hard。这正是复杂度理论建立一个困难问题库的方式。逻辑上,"若 P 可解则 Q 可解"与"Q 已知不可解"合推"P 不可解"。