其他分享
首页 > 其他分享> > POJ1651 Multiplication Puzzle (区间DP)

POJ1651 Multiplication Puzzle (区间DP)

作者:互联网

这道题的妙处在于把原问题看成矩阵连乘问题,求这些矩阵相乘的最小乘法次数,比如一个i*k矩阵乘一个k*j的矩阵,他们的乘法次数就是i*k*j (联想矩阵乘法的三层循环),题目说的取走一张牌,类似于矩阵相乘除去k,所以根据这个条件分析可以联想到矩阵。

题目要求首尾两端不可取,也就是求到最后只剩下一个矩阵(一共n-1个)。

用一个p数组就可以记录每个矩阵的行和列,比如:p[i],p[i+1],p[i+2]就可以表示一个i*(i+1)的矩阵和一个(i+1)*(i+2)的矩阵。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<iostream>
 7 #include<cmath>
 8 using namespace std;
 9 int dp[105][105],p[105];
10 
11 int solve(int n){
12     for(int d=2;d<=n;d++)
13         for(int i=1;i<=n-d+1;i++){
14             int j=i+d-1;
15             dp[i][j]=dp[i+1][j]+p[i-1]*p[i]*p[j];//k=i的情况,因为要取min,先拿出来计算,否则最小值一直都是0 
16             for(int k=i+1;k<j;k++)
17                 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j]);
18         }
19     return dp[1][n];
20 } 
21 
22 int main(){
23     int n;
24     scanf("%d",&n);
25     memset(dp,0,sizeof(dp));
26     for(int i=0;i<n;i++) scanf("%d",p+i);//用来存每个矩阵的行和列
27     printf("%d\n",solve(n-1));//n-1个矩阵
28     return 0; 
29 }

 

标签:int,Puzzle,矩阵,相乘,乘法,Multiplication,include,DP,105
来源: https://www.cnblogs.com/yhxnoerror/p/16387632.html