最优矩阵链乘(动态规划)
一个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)
1 #include<stdio.h> 2 int min(int a,int b) 3 { 4 return a<b?a:b; 5 } 6 int main() 7 { 8 int n,p[105],f[105][105]; 9 while(scanf("%d",&n)&&n) 10 { 11 int i,j,k; 12 for(i=0;i<=n;i++)scanf("%d",&p[i]); 13 for(i=1;i<=n;i++) 14 { 15 for(j=0;j<=n;j++)f[i][j]=1<<30; 16 f[i][i]=0; 17 f[i][i+1]=p[i-1]*p[i]*p[i+1]; 18 } 19 for(k=2;k<=n;k++) 20 for(i=1;i<=n-k;i++) 21 for(j=0;j<k;j++) 22 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])); 23 printf("%d\n",f[1][n]); 24 } 25 return 0; 26 }