矩阵连乘(有关区间dp)

  将每一个两两相乘的最优先记录好

先计算出小的区间的最优,于是可以推出大的区间的最优。以下是求解的顺序,先把1-2、2-3等等相差为1的计算出答案,

然后求1-3、 2-4等等相差为2的最优答案,以此类推,右上角的格子为问题的解。

2-5(即:2、 3、 4、 5)这个区间,可由2-3与3-5构成,还能由2-4与4-5构成,有下图。

看看实例.

算法设计例题:矩阵连乘(DP)

  • Time Limit: 1000/500 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others)
  • Total Submission(s): 1618     Accepted Submission(s): 545
Description

给定n个矩阵{ A1A2,…,An },保证AiAi+1是可乘的,i = 1,2,…,n-1。考察这n个矩阵的连乘积A1A2An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。现要求设计一个高效的算法,对给定的n个矩阵确定一个计算次序使得总的乘法次数最少,并输出该最优值。

Input

输入的第一行是单独一个整数T,表示案例的数目。每个案例的第一行是单独一个n ( 1 ≤ n≤ 50 ),表示矩阵的个数。接下来第n行,依序分别对应第i个矩阵,每行包括两个整数xiyi(1 ≤ i ≤ n,1 ≤ xi , yi ≤ 100 ),表示该矩阵的行数和列数。保证n个矩阵依序是可乘的。

Output

每个案例输出一个整数,表示最少需要的乘法次数。

Sample Input

1
4
50 10
10 40
40 30
30 5

Sample Output

10500

 1 #include<cstdio>
 2 using namespace std;
 3 const int maxn=60;
 4 int dp[maxn][maxn],a[maxn];///a记录每个行列
 5 
 6 int main()
 7 {
 8     int n,T;
 9     while( ~scanf("%d",&T)){
10         while( T--){
11             scanf("%d",&n);
12             for(int i=1;i<=n;i++){
13                 dp[i][i]=0;
14                 scanf("%d%d",&a[i-1],&a[i]); 
15     ///因为前一个的列等于后一个的行,所以可以进行覆盖
16             }
17 
18             int temp;
19             for(int num=2;num<=n;num++){ ///次数
20                 for(int i=1;i<=n-num+1;i++){
21                     int j=i+num-1; ///前一个的位置
22                     dp[i][j]=dp[i+1][j]+a[i-1]*a[i]*a[j]; ///按顺序计算的解。
23                     for(int k=i+1;k<=j-1;k++){
24                         temp=dp[i][k]+dp[k+1][j]+a[i-1]*a[k]*a[j];
25                     ///区间解
26                         if(dp[i][j]>temp)
27                             dp[i][j]=temp;
28                     }
29                 }
30             }
31             printf("%d
",dp[1][n]);
32         }
33     }
34     return 0;
35 }            
原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9092495.html