动态规划算法的基本要素
(1):最优子结构性质
(2):重叠子问题性质
动态规划法解题思路
(1):找出最优解的性质,并刻画其结构特征
(2):递归的定义最优值
(3):以自底向上的方式计算出最优值
(4):根据计算最优值得到的信息,构造最优解
动态规划与分治的主要区别
(1):分治的自顶向下进行计算的,动态规划是自底向上进行计算的
(2):动态规划法记录了已解决的子问题的解,分治法不记录
矩阵连乘问题的描述
给定N个矩阵A1,A2…An,其中,A(i)和A(i+1)是可乘的,确定计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少
解决思路
1:将N个矩阵的行列数存入一个大小为N+1的一维数组A中,即:A[0]为第一个矩阵的行数,A[1]为第一个矩阵的列数,又因为第一二个矩阵是可乘的,所以同时又是第二个矩阵的行数,依次存入N个矩阵的行列数
申请一个规格为(N+1) (N+1)的二维数组M用以记录动态规划中的一步步所得的子问题的解,规格为N+1是因为便于在填表时方便易懂。第0行,第0列不填。
再申请一个此规格的二维数组S,用以存储得出的最优子结构的分割点
2:我们再来详细解释一下1中的二维数组M的意义,M[i][j]的意义则代表从第i个矩阵乘到第j个矩阵所乘的最小次数,所以,我们最终所需的结果便是M[1][6]。
由上述亦可得,M表沿对角线左下部分是无用的,对角线上M[i][i]=0,S表亦是。
填完对角线的所有0之后,我们可以考虑填沿对角线向右上方向上的一层,比如M[1][2],M[2][3],M[3][4]…这些我们都可以直接填,因为,它们没有其他解可以比较
沿右上方向,我们再走一层,此时,我们考虑M[1][3],这时,我们知道我们可以(A1 A2) A3 即当2做cut点时,也可以A1 (A2 A3) 即当1做cut点时 。这时我们将这两种情况所得结果比较,取得最小次数存入。
这两种情况的结果如何得到呢?我们可以有这样的公式(当k为cut点时)times=M[i][k] + M[k+1][j] + A[i-1] A[k] * A[j]
这样,我们就可以依次填表,最后得到了M[1][N]
C代码实现
1 | #include <stdio.h> |
实验结果
1 | 0 0 0 0 0 0 0 |
感谢阅读,欢迎指正。