Archipelago

Lec 18动态规划 IV:杆切割、子集和与伪多项式时间

讲义完成更新于 2026-09-16

Lec 18 动态规划 IV:杆切割、子集和与伪多项式时间

资料依据:课程视频与 transcript · Lecture notes

TL;DR

  • 杆切割按剩余长度定义子问题,猜测第一段长度后递归求余下部分,总时间为 Θ(L2)\Theta(L^2)。
  • 子集和以元素位置 ii 和剩余目标 tt 为状态,在“选当前数”与“不选”两个分支之间取布尔或,时间为 O(nT)O(nT)。
  • O(nT)O(nT) 对数值 TT 是多项式,但对表示 TT 所需的 log⁡T\log T 位可能是指数级,因而子集和算法只是伪多项式时间。

本讲导览

  • 整数子问题
  • 伪多项式时间
  • 例子
    • 切割杆问题
    • 子集求和问题
  • DP 特性复习

切割杆问题

  • 给定一个长度为 L 的杆,和不同长度l\mathcal{l}的杆的价值 v(l\mathcal{l}), l∈{1,2,...L}\mathcal{l} \in \left\{{1,2,...L}\right\}

  • 目标:切割杆最大化切割杆价值

  • Ex: L = 7, v = [0, 1, 10, 13, 18, 20, 31,32]

  • 贪心算法能获得最大价值吗?

    • 不一定!

SRTBOT 分析:

  1. 子问题: x(l)x(\mathcal{l}): 切割长度l\mathcal{l}的杆能获得的最大价值,对于l∈{0,1,..L}\mathcal{l} \in \left\{0, 1, ..L\right\}成立

  2. 递归关联子问题解:

    • 第一块为长度 p(猜的!)
    • x(l)=max{v(p)+x(l−p)∣p∈{1...,l}}x(\mathcal{l}) = max \left\{v(p) + x(l-p) | p \in \left\{1..., \mathcal{l}\right\}\right\}
  3. 拓扑顺序

    • 对l\mathcal{l}增长: 子问题x(l)x(\mathcal{l})仅仅取决于严格递减的l\mathcal{l},所以不会成环。for l\mathcal{l} = 0, 1..., L

    • 子问题的 DAG 动态规划 IV:杆切割、子集和与伪多项式时间图示 1

  4. 基本情况

    • x(0) = 0
  5. 原始问题:

    • 长度为 L 的切割杆的最大价值是 x(L)
  6. 时间分析

    • 子问题数量: L+1
    • 每个子问题的工作量: O(l\mathcal{l}) = O(L)
    • O(L2L^2) 运行时间

Θ(L2)\Theta({L^2})这是一个多项式时间吗?

  • (强)多项式时间是指,运行时间被输入大小的常数次数多项式所界定,而输入大小以 word(字数)计算(这里例子中,因此这些数字都可以在机器字中存储)
  • 在杆切割问题中,输入大小是 L + 1 字(一个整数 L 和 在价值函数 v 的 L 个整数 )
  • O(L²) 是 L + 1 的常数次数多项式,因此答案是:是的,(强)多项式时间

子集求和

  • 输入: n 个正整数序列A={a0,a1,...,an−1}A = \left\{a_0, a_1, ..., a_{n-1}\right\}
  • 输出: 是否在存在 A 的子集,使其求和恰好等于 T?即是否存在 A 的子集 A',使得∑a∈A′a=T\sum_{a\in A'}a = T?
  • Ex: A = (1, 3, 4, 12, 19, 21, 22), T = 47, 可以找到子集 A' = {3, 4, 19, 21}
  • 这是个优化问题?
    • 不是,这是一个决策问题。答案是 YES or NO, True or False,而不是求最大值最小值这类优化问题。

SRTBOT 分析

  1. 子问题:

    • x(i,t)x(i, t) = A[i:]的子集求和为 t
    • i∈{0,1,...n}i \in \left\{0, 1, ...n\right\}, t∈{0,1,...T}t \in \left\{0,1, ...T\right\}
  2. 递归关联子问题解:

    • 思路:第一项aia_i 是否在 A 合法子集 S 内(Guess!)
    • 如果是,用剩余项尝试求和成t−ait - a_i
    • 如果不是,用剩余项尝试求和成 t
    • x(i,t)={x(i+1,t−ai) if ai≤t←ai∈Sx(i+1,t),其他情况←ai∉Sx(i, t) = \begin{cases} x(i+1, t-a_i) \text{ if } a_i\le t \leftarrow a_i \in S \\ x(i+1, t) ,其他情况 \leftarrow a_i \notin S \end{cases}
  3. 拓扑顺序

    • 子问题 x(i, t)仅仅依赖更大索引的子问题 x(i+1, t)或者 x(i+1, t-A[i])
    • 解决问题可以按照 i 严格递减的顺序(即从大到小)
  4. 基本情况

    • x(n,t)={Yes if t = 0No if t≠0x(n, t) = \begin{cases} Yes \text{ if t = 0} \\ No \text{ if } t \neq 0 \end{cases}
  5. 原始问题

    • x(0, T)

    • 解决所有子问题的 DAG

      • 至底向上

        动态规划 IV:杆切割、子集和与伪多项式时间图示 2

      • 至顶向下

        动态规划 IV:杆切割、子集和与伪多项式时间图示 3

  6. 时间分析

    • 子问题数目 O(nT), 每个子问题工作量为 O(1),因此需要 O(nT)时间

这是多项式时间吗?

  • 输入大小 n+1:整数 T 和 A 里面的 n 个整数
  • O(nT)被 n+1 的多项式界定吗?
    • n 和 T 的关系未知,T 可能是 n,n^2
    • 在 w-bit 的 Word-RAM 模型, 已知T≤2wT \le 2^w,w≥log⁡nw\ge \log{n},但是可能 w >> log n,我们并不知道 w 的上界
      • e.g. w=n 也是不合理的,运行时间就成了O(n2n)O(n2^n), 这是指数级的

伪多项式

  • 算法的伪多项式时间:运行时间上界由输入大小和输入整数的常次数多项式界定
  • 如果整数在输入大小上是多项式有界的,即nO(1)n^{O(1)}(与基数排序在 O(n)O(n) 时间内运行的情况相同),那么这种算法在这种情况下是多项式的
  • 计数排序 O(n+u),基数排序O(nlog⁡nu)O(n\log_n{u}),直接访问数组构建 O(n+u),斐波那契 O(n)都是伪多项式算法
  • 计数排序是弱多项式(基于强多项式和伪多项式之间的概念): 在以位数测量的输入大小(即输入整数的对数)上界由常数次多项式界定
  • 与切割杆问题相比,它是多项式的
    • 对 L 有伪多项式以来
    • 但幸运的是也有 L 个输入整数
    • 如果仅给出可销售杆长度的子集(背包问题,它推广了杆切割和子集和问题——见课堂讨论),那么算法将仅是伪多项式的

复杂度

  • 当整数不是多项式有界时,子集和问题可以在多项式时间内解决吗?
  • 如果 P ≠ NP,则不行。那是什么意思?下节课再讲!

总结动态规划特性

  • 如何定义子问题

    • 前缀、后缀问题:最大公共子序列,最大递增子序列

    • 子串问题: 交替硬币游戏,括号问题

    • 整数子问题:切割杆问题,子集和问题,斐波那契数列;

    • 多字符串问题:最大公共子序列

    • 顶点问题: SPS

    • 子问题约束/扩展

      • 非可扩展的限制: 最大递增子序列
      • 2x:交替硬币游戏,括号问题
      • θ(1)x: 钢琴指法问题
      • θ(x)x: Bellman-Ford
  • 递归关联子问题(如果子问题定义是正确的,那么你可以写出一个递归关系)

    • θ(1) 分支: 斐波那契数列, 保龄球得分问题, LCS,ACG,Floyd–Warshall
    • θ(degree) 分支: DAG, Bellman-ford
    • θ(n) branching: LIS, 括号问题, rod cutting
    • combine multiple sulution(not path in DAG): Fib, FW,括号
  • Original: combine multiple subprobs: DAG, LIS, B-F, F-W

我的理解

我的理解

分析含整数参数的算法时,必须区分“数值”与“编码长度”。杆切割的输入本身就列出 LL 个价格,而子集和只需 logTlog T 位就能给出很大的 TT,这一差别决定了复杂度的性质。