Loading

POJ 1651:Multiplication Puzzle(区间DP)

http://poj.org/problem?id=1651

题意:给出n个数字,每取中间一个数,就会使得权值加上中间这个数和两边的乘积,求取剩两个数最少的权值是多少。

思路:区间dp。

一开始想了挺久还是写不出方程,做了点别的事回来再想就突然觉得很简单了。

一开始使得长度为1和2的区间dp[i][j]为0.

然后dp[i][j] = min(dp[i][k] + dp[k][j] + w[k] * w[i] * w[j])。

枚举的k为中间拿掉的数,然后和左右的区间和相加就是最后答案了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 105
 6 typedef long long LL;
 7 LL dp[N][N], w[N];
 8 
 9 int main() {
10     int n;
11     while(~scanf("%d", &n)) {
12         memset(dp, 0x3f3f3f3f, sizeof(dp));
13         for(int i = 1; i <= n; i++) scanf("%lld", &w[i]);
14         for(int i = 1; i <= n; i++) dp[i][i] = dp[i][i+1] = 0;
15         //for(int i = 2; i < n; i++) dp[i][i] = w[i-1] * w[i] * w[i+1];
16         for(int len = 2; len < n; len++) {
17             for(int i = 1; i + len <= n; i++) {
18                 int j = i + len;
19                 for(int k = i + 1; k < j; k++)
20                     dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + w[i] * w[j] * w[k]);
21             }
22         }
23         printf("%lld\n", dp[1][n]);
24     }
25     return 0;
26 }

 

posted @ 2017-02-27 15:13  Shadowdsp  阅读(125)  评论(0编辑  收藏  举报