题意:多个矩阵连乘,矩阵相乘的顺序不同,计算的次数也不同。
分析:矩阵连乘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<iostream>
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;
}