矩阵连乘——动态规划
矩阵连乘:
参数描述:
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
*/