1.题目描述:——矩阵连乘积——动态规划实现
矩阵运算满足结合律,有的时候交换矩阵运算的顺序可以大大提高矩阵计算的速度和效率,
如何选择矩阵运算过程中交换的时间和次序是矩阵连乘积需要解决的问题。
2.解题分析
矩阵乘法满足结合律,即(AB)CD=A(BC)D,不同的计算次序产生的计算量差别很大,所以确定合适的计算次序很关键。若一个矩阵连乘积的计算次序完全确定,
即该连乘积已完全加括号,则可依此次序反复调用 2 个矩阵相乘算法计算矩阵连乘积,完全加括号的矩阵连乘积可递归地定义为:单个矩阵是完全加括号的;
如矩阵连乘积 A 是完全加括号的,则 A 可以表示为 2 个完全加括号的矩阵连乘积 B 和 C 的乘积并加括号,即 A = ( BC )。
3.代码实现:
#include<stdio.h>
#define NUM 51
int p[NUM];
int m[NUM][NUM];
int s[NUM][NUM];
void MatrixChain(int n)
{
for(int i = 1;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)
printf("A%d",i);
else
{
printf("(");
TraceBack(i,s[i][j]);
TraceBack(s[i][j]+1,j);
printf(")");
}
}
int main()
{
int n;
printf("输入矩阵的个数:");
scanf("%d",&n);
int i,temp;
printf("输入矩阵的维数:");
for(i = 0;i < n;i++)
printf("输入第%d个矩阵的维数:",n);
scanf("%d%d",&p[i],&temp);
p[n] = temp;
MatrixChain(n);
printf("%d\n",m[1][n]);
TraceBack(1,n);
return 0;
}