动态规划
基本要素:(1)最优子结构性质 (2)重叠子问题性质
步 骤:(1)找出最优解的性质,并刻画其结构特征
(2)递归地定义最优值
(3)以自底向上的方式计算最优值
(4)根据计算最优值时的信息构造最优解
自底向上的填表方法:(1)表的维数
(2)填表范围
(3)填表顺序
【例1】矩阵连乘问题
void MatixChain(int *p, int n, int **m, int **s){
for(int i = 1; i <= n; i++)
m[i][i] = 0;
for(int r = 2; r <= n; r++){
for(int i = 1; i <= n-r+1; i++){
int j = i+r-1;
m[i][j] = m[i+1][j] + p[i-1] * p[i] * p[j];
s[i][j] = i;
for(int k = i + 1; k < j; k++){
int t = m[i][k] + m[k+1][j] + p[i-1] * p[i] * p[j];
if(t < m[i][j]){
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
【动态规划——备忘录法】使用备忘录方法,直接将递归算法的计算时间从O(2n)降至O(n3).
【例2】最长公共子序列
(1)计算最优解 (由于每个数组单元的计算耗费O(1)时间,故此算法耗时O(mn))
(2)构造最长公共子序列 (打印出序列)
【例3】最大子段和
/*需要O(mn2)计算时间和O(mn)空间*/
动态规划算法与分治法类似,其基本思想是将等待求解的问题分解成若干子问题,先求解子问题,再结合子问题的解得到原问题的解。不同的是,适用于动态规划求解的问题经过分解得到的子问题往往不是独立的,为避免大量运算,借助一个表记录所有已解决的子问题的答案,不管是否用得到。
解决动态规划相关问题时,应先写出其递归方程,然后决定其填表方式以及顺序等。