矩阵连乘——动态规划

矩阵连乘:

     参数描述:                    

              A[i:j]:每个子矩阵链Ai ...Aj 对应的一个子问题
              p[i]:/每个矩阵的行数p[i-1]和列数p[i]
              m[i][j]:计算A[i:j]所需要的最少乘法次数——存储最优子结构
              m[1][n] :原问题的最优值
              s[i[j]:存储当前结构的最优断点

      A是一个pxq矩阵,B是一个qxr矩阵,矩阵A与矩阵B连乘,共需要p*r*q次数乘

动态规划:

 

 

 迭代方案:自底向上,从易到难

最容易的子问题:一个矩阵相乘。m[i][i]=0
计算所有两个矩阵AiAi+1相乘时的最优值m[i][i+1]
按照矩阵链长递增,依次计算:

 

代码实现:

#include<bits/stdc++.h>
#define maxn 105
using namespace std;
int n,p[1000];//每个矩阵的行数和列数
int m[100][100];//存储最优子结构
int s[100][100];//存储当前结构的最优断点
void MatrixChain() {
    for(int i=1; i<=n; i++) { //初始化主对角线为0,矩阵链长度为1
        m[i][i] = 0;     
    }
    for(int r=2; r<=n; r++) {  //依次计算第r条对角线
        for(int i=1; i<=n-r+1; i++) {   //每条对角线 的长度
            int j = i+r-1;    //对角线上每个元素的下标,i行j列
            m[i][j] = m[i][i]+m[i+1][j] +p[i-1]*p[i]*p[j],s[i][j] = i;
            for(int k=i+1;k<j;k++){   //枚举计算m[i][j]的最优解
                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;
                }
            }
        }
    }
}
void Traceback(int i,int j){
    if(i==j){
        return;
    }
    Traceback(i,s[i][j]);
    Traceback(s[i][j]+1,j);
    cout<<"Multiply A"<<i<<", "<<s[i][j];
    cout<<"and A"<<s[i][j]+1<<", "<<j<<endl;
}
int main() 
{
    memset(p,0,sizeof(p));
    memset(m,0,sizeof(m));
    memset(s,0,sizeof(s));
    cin >> n;
    for(int i=0;i<=n;i++){
        cin >> p[i];
    }
    MatrixChain();
    cout <<m[1][n]<<endl;
    Traceback(1,n);
    return 0;
}
/*
6
30 35 15 5 10 20 25
15125
*/
View Code

 

posted @ 2019-10-31 16:50  七忆鱼  阅读(279)  评论(0编辑  收藏  举报