问题:给定n个矩阵{A1, A2, …, An},Ai的维数为pi-1×pi,Ai与Ai+1是可乘的,i=1, 2 , …, n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少
解决:很明显当出现这种次数最少之类的话,我们首先应该想到动态规划,那么如何规划呢?
我们先写出一个dp表来看看dp[i][j]与子序列的关系
这里的颜色代表每次遍历的过程,dp[i][j] = Ai到Aj最少数乘次数,你可以看到我们遍历是斜着遍历的,我们现在来写动态规划的过程,首先要写出动态规划的状态转移方程
dp[i][j] = (i <= k <j) min{dp[i][k] + dp[k + 1][j] + dim[i] +* dim[k + 1] * dim[j]}
tips:我们要知道矩阵一次只能两个两个的计算,所以要确保每次循环只有两个矩阵相乘,所以我们用dp[0][3]来举例,dp[0][3] = min { dp[0][0] + dp[1][3] + dim[0]*dim[1]*dim[3] ,ddp[0][1] + dp[2][3] + dim[0]*dim[2]*dim[3],dp[0][2] + dp[3][3] + dim[0]*dim[1] *dim[3]}
这里dim是什么呢
dim是一个数组记录了矩阵的规模
所以我们可以写出总代码
public static void M(int n, int[][] dp, int[] dim){
for( int d = 1; d < n; d++ )
for( int i = 0; i < n - d; i++ )
{
int j = i + d;
int best_k = 0;
int min_value = 0;
for( int k = i; k < j; k++ )
{
int cur = dp[i][k] + dp[k+1][j] + dim[i] * dim[k+1] * dim[j+1];
if( cur < min_value )
{
min_value = cur;
best_k = k;
}
}
dp[i][j] = min_value;
}
}
public static void main(String[] args) {
int[][] dp;
dp = new int[100][100];
int[] dim = {5,200,2,100,30,200};
M(dim.length - 1,dp,dim);
System.out.print(dp[0][4]);
}
}