最优矩阵链乘(动态规划)

   一个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 }

 

posted @ 2013-05-03 00:11  再见~雨泉  阅读(1721)  评论(0编辑  收藏  举报