动态规划
动态规划是用来解决优化问题的,即要作出一组选择以达到最优解。动态规划有两个标志:一是可以划分最优子问题,二是子问题有重叠性(可以自底向上存储这些子问题的解,把算法效率从指数时间降到多项式时间)。
例如,动态规划可以运用在矩阵相乘上。在矩阵连乘的时候,在中间增加括号是不影响最后结果的。也就是说 A * B * C = A * ( B * C )。假设A、B、C的维数为10 X 100, 100 X 5 和5 X 50,那么两种方法的运算次数为7500次和75000次,相差10倍!因此我们可以使用动态规划来确定一个最优次序以达到减小运算量的目的。而为了确定次序而消耗的时间对比做矩阵乘法来说往往是很小的。
现在我们把矩阵连乘问题分解。假设m[i,j]是计算矩阵A[i..j]所需的标量乘法运算次数的最小值,那么计算全部矩阵的最小代价为m[i,n]。再假设每个矩阵Ai是P(i-1) X Pi的,那么有:
m[i,j] = min{ m[i,k] + m[k+1,j] + P(i-1) * Pk * Pj }
m[i,j] = 0 when i = j
但是我们不知道k的值,只好把k从i到j-1进行遍历,然后取最小的m[i,j]。这样,我们就得到了子问题的最优解。但是,这种算法是指数时间的,它的效率与蛮力破解差不多。为了提高速度,我们建立两个表格m和s。其中m记录每一个m[i,j]的值。s则记录计算m[i,j]时取得最有代价处k的值。为了更加直观的分析,我们常常在纸上画出这两张表格。
在计算m表格的时候使用自底向上的推进方式。比如,要计算m[2,5]需要使用
m[2,2], m[3,5]
m[2,3], m[4,5]
m[2,4], m[5,5]