Description
给定n个矩阵{ A1,A2,…,An },保证Ai与Ai+1是可乘的,i = 1,2,…,n-1。考察这n个矩阵的连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。现要求设计一个高效的算法,对给定的n个矩阵确定一个计算次序使得总的乘法次数最少,并输出该最优值。
Input
输入的第一行是单独一个整数T,表示案例的数目。每个案例的第一行是单独一个n ( 1 ≤ n ≤ 600 ),表示矩阵的个数。接下来第n行,依序分别对应第i个矩阵,每行包括两个整数xi,yi (1 ≤ i ≤ n,1 ≤ xi , yi ≤ 100 ),表示该矩阵的行数和列数。保证n个矩阵依序是可乘的。
Output
每个案例输出一个整数,表示最少需要的乘法次数。 运算过程及结果不会超出int范围。
Sample Input
1
4
50 10
10 40
40 30
30 5
Sample Output
10500
#include<iostream> using namespace std; #define N 600 #define INF 0x3f3f3f3f int p[N+1]; int m[N][N]; int n; void multiply() { for(int i=0;i<n;++i){ m[i][i]=0; } for(int i=1;i<n;++i){ for(int j=0;j<n-i;++j){ m[j][j+i]=INF; for(int k=0;k<i;++k){ if(m[j][j+i]>m[j][j+k]+m[j+k+1][j+i]+p[j]*p[j+k+1]*p[j+i+1]){ m[j][j+i]=m[j][j+k]+m[j+k+1][j+i]+p[j]*p[j+k+1]*p[j+i+1]; } } } } } int main() { int T; cin>>T; while(T--){ cin>>n; int temp,k=0; for(int i=0;i<n;++i){ for(int j=0;j<2;++j){ cin>>temp; if((i==0&&j==0)||j==1){ p[k++]=temp;///只需要读取n+1个数据 } } } multiply(); cout<<m[0][n-1]<<endl; } return 0; }