动态规划的具体操作,分四步
动态规划是我学的最蛋 疼的一个问题。大家觉得呢
•动态规划算法的一般步骤
1.找出最优解的性质,并刻画其结构特征;
2.递归地定义最优值;
3.以自底向上的方式计算出最优值;
根据计算最优值时得到的信息,构造最优解
下面用一个例子来说明。
矩阵连乘问题(自行百度查一下是什么哈)
•将矩阵连乘积AiAi+1…Aj记作A[i:j]
–把问题转化成考察A[1:n]的最优计算次序问题
–设计算次序在A[k]处将矩阵断开最优,则总计算量为: A[1:k] 的计算量加上A[k+1:n]的计算量,再加上A[1:k] 和A[k+1:n]相乘的计算量。
关键特征
lA[1:n]的最优计算次序所包含的计算矩阵子链A[1:k]和A[k+1:n]的次序也是最优的。(可用反证法证明)
——问题的最优解包含了其子问题的最优解,这种性质称为最优子结构性质。
对矩阵:A1A2A3A4A5A6,可能的最优解A1(A2A3)|A4(A5A6)
最优解:A[1:6]=A[1:3]+A[4:6]+A[1:3]*A[4:6]
–A[1:3]与A[4:6]也必分别为最优解(计算总量最少),因为其无关;
–若有A’[1:3]小于A[1:3],由后两项不改变,则A[1:6]不是最小,故与前提矛盾;
递归地定义最优值。
•设计算A[i:j],1≤i≤j ≤n,所需的最少数乘次数为m[i][j]
——则原问题的最优解为m[1][n]
–考察两种情况
•i=j;
•i<j;
m[i][j] = 0+m[i+1][j]+ p[i-1]*p[i]*p[j];
for (k = i+1; k < j; k++) {
t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if (t < m[i][j]) m[i][j] = t;
}
void MatrixChain(int *p,int n,int **m,int **s) { for (j = 2; j <= n; j++) for (i = j-1; i >= 1; i--) { m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j]; s[i][j] = i; for (k = i+1; k < j; k++) { t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]; if (t < m[i][j]) { m[i][j] = t; s[i][j] = k; } } } } //算法的计算时间上界为O(n3)