Lec 8. Dynamic Programming¶
约 659 个字 5 行代码 预计阅读时间 2 分钟
Dynamic programming takes practice to perfect.
—— Algorithm Illuminated, [ 美 ] Tim Roughgarden
Dynamic Programming¶
适合应用动态规划方法求解的最优化问题应该具备的两个要素:
-
最优子结构;
-
子问题重叠。
我们通常按如下 4 个步骤来设计一个动态规划算法:
-
刻画一个最优解的结构特征;
-
递归地定义最优解的值;
-
计算最优解的值,通常采用自底向上的方法;
-
利用计算出的信息构造一个最优解。
Fibonacci Numbers¶
数楼梯问题。
Ordering Matrix Multiplications¶
问题:以何种顺序计算 \(n\) 个矩阵的乘积,可以使计算时间最小?
假设我们需计算 \(n\) 个矩阵 \(M_1 \times M_2 \times \cdots \times M_n\) 的乘积,其中 \(M_i\) 是一个 \(r_{i-1} \times r_i\) 矩阵;计算 \(M_i \times M_{i+1}\) 的代价为 \(r_{i-1}r_ir_{i+1}\)。令 \(m_{ij}\) 表示计算 \(M_i \times M_{i+1} \times \cdots \times M_j\) 的最优代价,则
Optimal Binary Search Tree¶
最优二叉搜索树:给定 \(N\) 个单词 \(w_1 < w_2 < \cdots < w_N\),每个单词 \(w_i\) 被搜索的概率为 \(p_i\)。将这些单词排列在二叉搜索树中,以最小化期望总访问时间
设 \(c_{ij}\) 为 \(w_i, \ldots, w_j\) 的最小代价;规定 \(c_{ii} = p_i\),且当 \(j > i\) 时 \(c_{ij} = 0\);则
时间复杂度为 \(O(N^3)\);使用 Knuth 优化后可达 \(O(N^2)\)。
WIP
All-Pairs Shortest Path¶
全源最短路问题:求每对结点之间的最短路。
使用邻接矩阵存图,顶点 \(0 \leq i, j < n\)。令 \(D_{ij}^k\) 表示从 \(i\) 到 \(j\) 的最短路径长度,且该路径的所有中间顶点(不含端点 \(i\) 和 \(j\))需来自集合 \(\{0, 1, \dots, k\}\);规定 \(D_{ij}^{-1} = \text{Cost}_{ij}\)。则我们需要的从 \(i\) 到 \(j\) 的最短路为 \(D_{ij}^{N-1}\)。其满足状态转移方程
使用 \(k, i, j\) 三层循环实现即可,时间复杂度为 \(O(|V|^3)\)。
即 Floyd 算法。
推荐阅读
0-1 Knapsack Problem¶
0-1 背包问题:已知第 \(i\) 个物品的重量 \(w_{i}\),价值 \(v_{i}\),与背包的总容量 \(W\),求所能达到的最大总价值。
设 \(f_{i, j}\) 为在只能放前 \(i\) 个物品的条件下容量为 \(j\) 的背包所能达到的最大总价值,则
可做滚动数组优化,去掉第一维:
此时注意 \(j\) 需要从 \(W\) 枚举到 \(w_i\),以保证 \(f_{i,j}\) 总在 \(f_{i, j - w_i}\) 之前被更新。
Example
推荐阅读