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