poj1651 Multiplication Puzzle(区间dp)

https://vjudge.net/problem/POJ-1651

类似矩阵链乘,dp[i][j]表示取走(i, j)中所有数的最小情况,而转移方程dp[i][j]=min(dp[i][j], dp[i][k]+dp[k][j])表示最后取走的时k的情况

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n, dp[110][110], a[110];
 7 int main()
 8 {
 9     memset(dp, 0, sizeof(dp));
10     cin >> n;
11     for(int i = 0; i < n; i++){
12         cin >> a[i];
13     }
14     for(int i = 0; i < n-2; i++){
15         dp[i][i+2] = a[i]*a[i+1]*a[i+2];//初始化,3个数
16     }
17     for(int l = 3; l < n; l++){//从4个数开始
18         for(int i = 0; i<n-l; i++){
19             int j = i+l;
20             for(int k = i+1; k < j; k++){//不能取走头尾
21                 if(!dp[i][j]){
22                     dp[i][j] = dp[i][k]+dp[k][j]+a[i]*a[k]*a[j];
23                     //cout <<dp[i][j];
24                 }
25                 else dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]);//开区间中,最后一个取走的是k的话
26             }
27         }
28     }
29     cout << dp[0][n-1] << endl;
30     return 0;
31 }

 

posted @ 2018-04-20 21:55  Surprisez  阅读(103)  评论(0编辑  收藏  举报