特征:计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]的次序也是最优的。
如计算 A1*A2*A3*A4*A5*A6
/** int [] p 存放各个矩阵的列 int [][] m 所需要的最少数乘次数m[i,j] 1≤i≤j≤n, 最后乘法次数为 m[1][n]; int [][] s s[i][j]:存放的值为相对于m[i][j] 的断开位置 */ void matrixChain(int [] p, int [][] m, int [][] s) { for (int i = 1; i <= n; i++) m[i][i] = 0; //自身相乘,次数为0 for (int r = 2; r <= n; r++) //先计算2个矩阵相乘次数,然后3个,4个... for (int i = 1; i <= n-r+1; i++) { // int j=i+r-1; //当前矩阵总个数 m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j]; //m[i][j]初始化为 从i分割 ,实际还加了m[i][i],为0 s[i][j] = i; //从i分割 for (int k = i+1; k < j; k++) { //枚举每个位置 为分割点 int 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;} } } }
下面这种方法在 书上叫 备忘录 ;
这种方法是自顶向下的
int lookupChain(int i,int j){ if(m[i][j]>0) return m[i][j]; if(i==j) return 0; m[i][j] = lookupChain(i+1,j) + p[i-1]*p[i]*p[j]; 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<m[i][j]) m[i][j] = t; } return m[i][j]; }