Lec 18动态规划 IV:杆切割、子集和与伪多项式时间
Lec 18 动态规划 IV:杆切割、子集和与伪多项式时间
资料依据:课程视频与 transcript · Lecture notes
TL;DR
- 杆切割按剩余长度定义子问题,猜测第一段长度后递归求余下部分,总时间为 。
- 子集和以元素位置 和剩余目标 为状态,在“选当前数”与“不选”两个分支之间取布尔或,时间为 。
- 对数值 是多项式,但对表示 所需的 位可能是指数级,因而子集和算法只是伪多项式时间。
本讲导览
- 整数子问题
- 伪多项式时间
- 例子
- 切割杆问题
- 子集求和问题
- DP 特性复习
切割杆问题
-
给定一个长度为 L 的杆,和不同长度的杆的价值 v(),
-
目标:切割杆最大化切割杆价值
-
Ex: L = 7, v = [0, 1, 10, 13, 18, 20, 31,32]
-
贪心算法能获得最大价值吗?
- 不一定!
SRTBOT 分析:
-
子问题: : 切割长度的杆能获得的最大价值,对于成立
-
递归关联子问题解:
- 第一块为长度 p(猜的!)
-
拓扑顺序
-
对增长: 子问题仅仅取决于严格递减的,所以不会成环。for = 0, 1..., L
-
子问题的 DAG

-
-
基本情况
- x(0) = 0
-
原始问题:
- 长度为 L 的切割杆的最大价值是 x(L)
-
时间分析
- 子问题数量: L+1
- 每个子问题的工作量: O() = O(L)
- O() 运行时间
这是一个多项式时间吗?
- (强)多项式时间是指,运行时间被输入大小的常数次数多项式所界定,而输入大小以 word(字数)计算(这里例子中,因此这些数字都可以在机器字中存储)
- 在杆切割问题中,输入大小是 L + 1 字(一个整数 L 和 在价值函数 v 的 L 个整数 )
- O(L²) 是 L + 1 的常数次数多项式,因此答案是:是的,(强)多项式时间
子集求和
- 输入: n 个正整数序列
- 输出: 是否在存在 A 的子集,使其求和恰好等于 T?即是否存在 A 的子集 A',使得?
- Ex: A = (1, 3, 4, 12, 19, 21, 22), T = 47, 可以找到子集 A' = {3, 4, 19, 21}
- 这是个优化问题?
- 不是,这是一个决策问题。答案是 YES or NO, True or False,而不是求最大值最小值这类优化问题。
SRTBOT 分析
-
子问题:
- = A[i:]的子集求和为 t
- ,
-
递归关联子问题解:
- 思路:第一项 是否在 A 合法子集 S 内(Guess!)
- 如果是,用剩余项尝试求和成
- 如果不是,用剩余项尝试求和成 t
-
拓扑顺序
- 子问题 x(i, t)仅仅依赖更大索引的子问题 x(i+1, t)或者 x(i+1, t-A[i])
- 解决问题可以按照 i 严格递减的顺序(即从大到小)
-
基本情况
-
原始问题
-
x(0, T)
-
解决所有子问题的 DAG
-
至底向上

-
至顶向下

-
-
-
时间分析
- 子问题数目 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 模型, 已知,,但是可能 w >> log n,我们并不知道 w 的上界
- e.g. w=n 也是不合理的,运行时间就成了, 这是指数级的
伪多项式
- 算法的伪多项式时间:运行时间上界由输入大小和输入整数的常次数多项式界定
- 如果整数在输入大小上是多项式有界的,即(与基数排序在 时间内运行的情况相同),那么这种算法在这种情况下是多项式的
- 计数排序 O(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
我的理解
我的理解
分析含整数参数的算法时,必须区分“数值”与“编码长度”。杆切割的输入本身就列出 个价格,而子集和只需 位就能给出很大的 ,这一差别决定了复杂度的性质。