矩阵乘这个算法 中,典型的运用了动态规划算法,首先是具有最有子结构(该序列最优的相乘顺序使得乘法次数最小,那么他的子序列也要具有最有的相乘顺序使得子序列的乘法次数最小,比如 设m[1][n]表示矩阵的最小乘法次数,那么可以化解为m[1][k]+m[k+1][n]+p[0]*p[k]*p[n] 而如何确定k 了,那么就可以一次又一次的试了,比如K=1,2,3直到n-1;当然这个是从上往下,这样容易思考些,而为了,减少 计算次数,我们可以从下往上的计算(好像大部分动态算法,都是从上往下的思考,从下往上的计算)
#include<iostream>
using namespace std;
const int Anum=6;
static int p[Anum+1]={30,35,15, 5,10,20,25};//这是矩阵行列数
static int m[Anum][Anum]={0};
static int s[Anum][Anum]={0};
void MatrixChain(int *p,int n,int m[Anum][Anum],int s[Anum][Anum]);
void Traceback(int i,int j,int s[Anum][Anum]);
void main()
{MatrixChain(p,Anum,m,s);
Traceback(1,Anum,s);
}
void Traceback(int i,int j,int s[Anum][Anum])//对书本上的Traceback 加以改造,从而得到加括号的实现首先 根据算法的由外向里,
//现在每一层的调用外部添加括号,然后最后分归为只有一个元素,和有两个元素
{if(i==j){
cout<<"A"<<i;
return;}
if((i+1)==j)
{
cout<<"(A"<<i<<","<<"A"<<j<<")";
return;}
else
{
cout<<"(";
Traceback(i,s[i][j],s);
Traceback(s[i][j]+1,j,s);
cout<<")";
return;
}
}
void MatrixChain(int *p,int n,int m[Anum][Anum],int s[Anum][Anum])
{for(int i=1;i<=n;i++) m[i][i]=0;//当只有一个矩阵时,无需乘
for(int r=2;r<=n;r++) //共要进行n-2+1次的大循环
for(int i=1;i<=n-r+1;i++)//在每次大循环中,进行循环的起始行数,和终止行数
{int j=i+r-1; //当前计算的列数开始位置
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++){ //在i+1->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;}
}
}}