题目描述:
给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括号的方法表示矩阵连乘的次序,不同的计算次序计算量(乘法次数)是不同的,找出一种加括号的方法,使得矩阵连乘的次数最小。算法:构造递归解:设m[i,j]为矩阵链Ai…Aj的最优解的计算花费代价
代码一:
#include <iostream>
#include <cstdlib>
using namespace std;
int m[100][100];
int s[100][100];
void MatrixChain(int *p,int n)//求最优值
{
for(int i=0;i<=n;i++)
m[i][i]=0;
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+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<<"Multipy A"<<i<<","<<s[i][j];
cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;
}
int main()
{
int p[]={30,35,15,5,10,20,25};
MatrixChain(p,6);
cout<<m[1][6]<<endl;
Traceback(1,6);
return 0;
}
代码二:
#include <iostream>
#include <cstdlib>
using namespace std;
int m[100][100];
int s[100][100];
int p[7]={30,35,15,5,10,20,25};
int LookupChain(int i,int j)
{
if(m[i][j]>0) //表示相应的子问题已经被计算过了,直接返回结果即可
return m[i][j];
if(i==j)
return 0;
int u=LookupChain(i,i)+LookupChain(i+1,j)+p[i-1]*p[i]*p[j];
s[i][j]=i;
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<u)
{
u=t;
s[i][j]=k;
}
}
m[i][j]=u;
return u;
}
int MemoizeMatrixChain(int n)//求最优值
{
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
m[i][j]=0;
return LookupChain(1,n);
}
void Traceback(int i,int j)//求最优解
{
if(i==j)
return;
Traceback(i,s[i][j]);
Traceback(s[i][j]+1,j);
cout<<"Multipy A"<<i<<","<<s[i][j];
cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;
}
int main()
{
MemoizeMatrixChain(6);
cout<<m[1][6]<<endl;;
Traceback(1,6);
return 0;
}