6 动态规划
6.1 重新审视DAG的最短路径问题
- 有向无环图DAG的节点可以被线性化:
procedure dag-shortest-paths(G,l,s)
Input: Graph G=(V,E), dag;
edge lengths {le:e ∈ E};
vertex s ∈ V
Output: For all vertices u reachable from s,dist(u) is set
to the distance from s to u.
for all u ∈ V
dist(u)= ∞
dist(s)=0
Linearize G //通过深度优先搜索线性化(拓扑排序)
for each u ∈ V in Linearized order:
for all edges (u,v) ∈ E:
dist(v)=min(dist(u)+l(u,v))
6.2 最长递增子序列
for j=1,2,...,n
L(j)=1+max{L(i):(i,j) ∈ E}
return L
//i为j的前驱,求反转图Gr即可
6.3 编辑距离
将两个单词进行对齐,对齐代价为对应字母不相同的列数
6.3.1 一种动态规划的解
寻找两个字串: x[1...m],y[1...n] 之间的编辑距离 E(m,n) ,考虑字符串的前缀: x[1...i],y[1...j] 的编辑距离 E(i,j) 。
则:
E(i,j)=min{
1+E(i−1,j),1+E(i,j−1),diff(i,j)+E(i−1,j−1)}
for i=0,...,m:
E(i,0)=i
for j=0,...,n:
E(0,j)=j
for i=1,...,m:
for j=1,...,n:
E(i,j)=min{
1+E(i-1,j),1+E(i,j-1),diff(i,j)+E(i-1,j-1)}
return E
6.3.2 隐含的dag
每个动态规划都隐含着一个dag结构:每个节点表示一个子问题,每条边表示解决子问题时的先后约束。
除边 { (i−1,j−1)→(i,j):x[i]=y[j]} 为0外,其余边为0;问题转为求点 s=(0,0) 到点 t=(m,n) 的最短距离。
其中,为使 EXPONENTIAL 转为 POLYNOMIAL
- 向下表示删除
- 向右表示插入
向对角线表示匹配或替换
6.4 背包问题
- n件物品,W总重量的背包,复杂度 O(nW)
6.4.1 多副本背包问题
- Knapsack with repetition