问题描述
给定6个矩阵{A1,A2,A3,A4,A5,A6},其中Ai和Ai+1是可乘的(i=1,2,…,5)。考察这6个矩阵的连乘积A1A2A3A4A5A6。
A1 | A2 | A3 | A4 | A5 | A6 |
---|---|---|---|---|---|
30*35 | 35*15 | 15*5 | 5*10 | 10*20 | 20*25 |
最终输出的得到结果应为:
15125
((A1(A2A3))((A4A5)A6)
基本思想
- 分析最优解的结构
- 建立递归关系
- 计算最优值
- 构造最优解
本例 矩阵经乘积计算量从下往上算,边从左往右推进
源码
#include<stdio.h>
#include<stdlib.h>
// 矩阵的行列数组p[],最优值数组m[],最优断开位置的数组s[]
void MatrixChain(int *p,int n,int **m,int **s)
{
for (int i = 1; i < n; i++)
{
m[i][i]=0;
}
// 表示边r从第二条边开始算起,自底向上计算
for (int r = 2; r <=n; r++)
{
// i表示每边有多少计算单位
for (int i = r-1; i >=1; i--)
{
int j=r;
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;
// k表示断点位置
s[i][j]=k;
}
}
}
}
}
//根据最优值求最优解
void Trackback(int i,int j,int **s)
{
if (i==j)
{
return;
}
Trackback(i,s[i][j],s);
Trackback(s[i][j]+1,j,s);
if(!((i==s[i][j])&&(s[i][j]==j-1)))
printf("Multtply A [%d , %d] and A [%d , %d]\n",i,s[i][j],s[i][j]+1,j);
}
int main(int argc, char const *argv[])
{
int p[]={30,35,15,5,10,20,25};
int **m=(int **)malloc(sizeof(int*)*20);
int **s=(int **)malloc(sizeof(int*)*20);
for (int i = 0; i < 20; i++)
{
m[i]=(int *)malloc(sizeof(int)*20);
s[i]=(int *)malloc(sizeof(int)*20);
}
MatrixChain(p,7,m,s);
printf("%d\n",m[1][6]);
Trackback(1,6,s);
return 0;
}