动态规划-矩阵连乘

特征:计算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];
}