动态规划法
适用情况:
1. 问题可以分为多个阶段(如用1个的阶段,用2个的阶段,.......)
2. 无后效性: 每个阶段可以由前面的阶段决定(这样就减少了运算),但不能有后面的阶段反过去影响前面阶段
3. 重叠性:各阶段存在重复运算,尤其是后阶段依赖前阶段的结果
步骤:
1. 划分阶段
2. 确定阶段转移方程式
3. 确定边界条件
例子:
// 求解图的连通表 // 如果顶点1和顶点2连通,那么T[1][2]=1;反之,T[1][2] = 0 // 划分n个阶段,第k个阶段表示,i,j之间是否连通,中间结点最多只能用节点k // 状态转移方程: 如果只用k-1的中间节点,i,j之间就连通,那么用k的中间节点,更是连 // 通的; 反之,如果i,k之间连通,且k,j之间连通,那么此时i,j才连通 // T(k)[i][j] = T(k-1)[i][j] || ( T(k-1)[i][k] && T(k-1)[k][j] ) void f() { for k=0 to k=n for i=0 to i=n for j=0 to j=n T[i][j] = T[i][j] || (T[i][k] && T[k][j]) }
例子:最长公共子序列
斐波那契数列:填关于n的一维表
背包问题:填关于i、j(前i个物品,最大容量)的二维表