质。
(一)最优子结构
矩阵连乘计算次序问题的最优解包含着其子问题的最优解。这种性质称为最优子结构性质。
在分析问题的最优子结构性质时,所用的方法具有普遍性:首先假设由问题的最优解导出
的子问题的解不是最优的,然后再设法说明在这个假设下可构造出比原问题最优解更好的
解,从而导致矛盾。
利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个
问题的最优解。最优子结构是问题能用动态规划算法求解的前提。
注意:同一个问题可以有多种方式刻划它的最优子结构,有些表示方法的求解速度更快
(空间占用小,问题的维度低)
()重叠子问题
递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
这种性质称为子问题的重叠性质。动态规划算法,对每一个子问题只解一次,而后将其解
保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果。 通
常不同的子问题个数随问题的大小呈多项式增长。因此用动态规划算法只需要多项式时间,
从而获得较高的解题效率。
(三)备忘录方法
备忘录方法的控制结构与直接递归方法的控制结构相同,区别在于备忘录方法为每个解过
的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求解。
int LookupChain(int i,int j)
{if (m[i][j] > 0) return m[i][j];if (i == j) return 0;
int u = LookupChain(i,i) + LookupChain(i+1,j) + p[i-1]*p[i]*p[j];
s[i][j] = i;for (int k = i+1; k < j; k++) {
int t = LookupChain(i,k) + LookupChain(k+1,j) + p[i-1]*p[k]*p[j];
if (t < u) { u = t; s[i][j] = k;}}
m[i][j] = u;return u;}
算法复杂性:T(n)=O(n3),矩阵连乘积的最优计算次序问题可用自顶向下的备忘录方法或
自底向上的动态规划算法在 O(n3)计算时间内求解。
适用条件:一般来说,当一个问题的所有子问题都至少要解一次时,用动态规划算法比用
备忘录方法好。此时,动态规划算法没有任何多余的计算,还可以利用其规则的表格存取
方式来减少在动态规划算法中的计算时间和空间需求。当子问题空间中部分子问题可以不
必求解时,易用备忘录方法则较为有利,因为从其控制结构可以看出,该方法只解那些确
实需要求解的子问题。
三、最长公公子序列共有 2
m
不同的子序列
(一)计算最优值
子问题空间中有 θ(mn)个不同子问题,动态规划自底向上计算最优值能提高算法效率。
void LCSLength(int m,int n,char *x,char *y,int **c,int **b)
{ int i,j;for (i = 1; i <= m; i++) c[i][0] = 0;
for (i = 1; i <= n; i++) c[0][i] = 0;for (i = 1; i <= m; i++)for (j = 1; j <= n; j++) {
if (x[i]==y[j]) { c[i][j]=c[i-1][j-1]+1; b[i][j]=1;}
else if (c[i-1][j]>=c[i][j-1]) {c[i][j]=c[i-1][j]; b[i][j]=2;}
else { c[i][j]=c[i][j-1]; b[i][j]=3; }}}
(二)构造最长公共子序列进一步的分析还可将空间需求减至 O(min(m,n))。