动态规划-矩阵连乘

题意:多个矩阵连乘,矩阵相乘的顺序不同,计算的次数也不同。
分析:矩阵连乘AiAi+1Ai+2……Aj的最优解问题。
1.假设在第k位置上找到最优解,则问题变成了两个子问题:(AiAi+1……Ak),(Ak+1……Aj)因此矩阵连乘划分括号有最优子结构可以使用动态规划
2.定义表达式:m[i][j]表示矩阵Ai到矩阵Aj连乘计算所需的最小次数。 m[i][j]=m[i][k]+m[k][j]+p[i-1]*p[k+1]*p[j]; 其中p[i-1]表示矩阵Ai的行数(i=1…j),p[j]表示最后一个矩阵的列数

#include
using namespace std;
int p[1005];
int m[1005][1005]={0},s[1005][1005]={0};
int n;
void matrixchain(){
    //r类似于滑动窗口,表示连乘矩阵的个数。
    //m[1][2]、m[2][3]...m[n-1][j] 其中r=2
    //m[1][3]、m[2][4]...m[n-2][j] 其中r=3
    //m[1][r]、m[2][r+1]...m[n-r-1][j]其中r=r
    for(int r=2;r<=n;r++){
        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];
            s[i][j]=i;  //代表括号分开的地方
            for(int k=i+1;k<j;k++){
                int t=m[i][k]+m[k][j]+p[i-1]*p[k+1]*p[j];
                if(t<m[i][j]){
                    m[i][j]=t;
                    s[i][j]=t;
                }
            }
        }
    }
}
void print(int i,int j){
    if(i==j){
        cout<<"A["<<i<<"]";
        return;
    }
    cout<<"(";
    print(i,s[i][j]);
    print(s[i][j]+1,j);
    cout<<")";
}
int main()
{
    cout<<"输入矩阵的个数n: "<<endl;
    cin>>n;
    cout<<"依次输入每个矩阵的行数和最后一个矩阵的列数:"<<endl;
    for(int i=0;i<=n;i++)
        cin>>p[i];
    matrixchain();
    print(1,n);
    cout<<"最小计算次数为: "<<m[1][n]<<endl;
    return 0;
}

你可能感兴趣的:(动态规划)