最优矩阵链乘(动态规划)
一个n*m的矩阵由n行m列共n*m排列而成。两个矩阵A和B可以相乘当且仅当A的列数等于B的行数。一个n*m的矩阵乘m*p的矩阵,运算量为n*m*p。
矩阵乘法不满足分配律,但满足结合律。因此A*B*C既可以按顺序(A*B)*C也可以按A*(B*C)来进行。假设A、B、C分别是2*3、3*4、4*5的,则(A*B)*C运算量是2*3*4+2*4*5=64,A*(B*C)的运算量是3*4*5*2*3*5=90.显然第一种顺序节省运算量。
给出n个矩阵组成的序列,设计一种方法把他们依次乘起来,使得总的运算量尽量小。假设第i个矩阵A[i]是P[i-1]*P[i]的。
输入
3
2 3 4 5
输出
64
用f(i,j)表示A[i]、A[i+1]...A[j]乘起来的最少运算数
状态转移方程
f(i,j)=min{ f(i,j), f(i,k) + f(k+1,j) + P[i-1]*P[k]*P[j] }(i=<k<j)
#include<stdio.h>
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int n,p[105],f[105][105];
while(scanf("%d",&n)&&n)
{
int i,j,k;
for(i=0;i<=n;i++)scanf("%d",&p[i]);
for(i=1;i<=n;i++)
{
for(j=0;j<=n;j++)f[i][j]=1<<30;
f[i][i]=0;
f[i][i+1]=p[i-1]*p[i]*p[i+1];
}
for(k=2;k<=n;k++)
for(i=1;i<=n-k;i++)
for(j=0;j<k;j++)
f[i][i+k]=min((f[i][i+j]+f[i+j+1][i+k]+p[i-1]*p[i+j]*p[i+k]),(f[i][i+k]));
printf("%d\n",f[1][n]);
}
return 0;
}