应当有最优子结构和重叠子问题
最长公共子序列(lcs)
LCS例子:
-
字符串1:
"monkey" -
字符串2:
"human"
我们来构建状态转移表
h u m a n
0 0 0 0 0 0
m 0 0 0 1 1 1
o 0 0 0 1 1 1
n 0 0 0 1 1 2
k 0 0 0 1 1 2
e 0 0 0 1 1 2
y 0 0 0 1 1 2
如果两个字母相同:左上角数字 + 1
如果两个字母不同:左边数字 和 上边数字 中取大的
怎么理解?
如果字母相同则证明lcs长度加1,选择左上角是因为这是上一个状态
取大的则是因为现在lcs不能加一,所以只能找之前最好的结果
背包问题
例子:背包容量:5公斤
-
物品:
-
物品1:价值6,重量1
-
物品2:价值10,重量2
-
物品3:价值12,重量3
-
物品4:价值13,重量4
-
容量: 0 1 2 3 4 5
物品0: 0 0 0 0 0 0
物品1: 0 6 6 6 6 6
物品2: 0 6 10 16 16 16
物品3: 0 6 10 16 18 22
物品4: 0 6 10 16 18 22
对于每个格子
不装当前物品:价值 = 上一行同列的值
装当前物品:价值 = 当前物品价值 + 左上角某个格子的值
取两者中大的那个
时间复杂度 = O(nW)
-
n= 物品数量 -
W= 背包容量(一个具体的数字)
时间复杂度
我们在这里再次明确一下时间复杂度
O(nW)不是真正的多项式时间
因为当w越大,我们就需要更大的空间来存储w这个数
真多项式时间时间复杂度 O(n²) → 相对于输入长度是多项式的
假多项式时间总输入长度 ≈ n + logW
但时间复杂度 O(nW) = O(n × 2^(logW))相对于输入长度是指数级的
旅行售货商问题(TSP)
有n个城市,每两个城市间有距离cij,找一条经过所有城市恰好一次并回到起点的最短环路
定义状态:
f(当前城市, 剩余城市集合, 终点) = 从当前城市出发,经过剩余城市,到达终点的最短距离
假设城市:A, B, C, D,起点是A
第一步:解决最简单的问题
-
从B出发,没有剩余城市,直接回A:距离 = B到A的距离
-
从C出发,没有剩余城市,直接回A:距离 = C到A的距离
-
从D出发,没有剩余城市,直接回A:距离 = D到A的距离
第二步:解决稍复杂的问题
-
路线:B→C→A距离 = B到C的距离 + (C到A的距离)
-
路线:B→D→A距离 = B到D的距离 + (D到A的距离)
第三步:解决更复杂的问题
-
选择1:B→C→D→A = B到C + (C出发,剩D到A)
-
选择2:B→D→C→A = B到D + (D出发,剩C到A)
-
取较短的那个
一次次类推
最后:解决原问题
从A出发,还剩B,C,D:
-
选择1:A→B→(B出发,剩C,D到A)
-
选择2:A→C→(C出发,剩B,D到A)
-
选择3:A→D→(D出发,剩B,C到A)
-
取最短的那个
6521

被折叠的 条评论
为什么被折叠?



