区间型动态规划 之 CODE[VS] 1154 能量项链 (2006年NOIP全国联赛提高组)

/*
思路同:CODE[VS] 1048 石子归并
dp[i][k] := i到k的珠子,所能获得的最大能量
dp[i][k] = max(dp[i][k], dp[i][j] + dp[j+1][i+k] + arr[i]*arr[j+1]*arr[i+k+1])
 
注意:
此题为循环“石子归并”,空间开为两倍(将循环转换为线性解决),输出结果max(dp[i][i+(N-1)])
*/
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <locale>
 6 #include <cmath>
 7 #include <vector>
 8 using namespace std;
 9 const int INF = 0x3f3f3f3f;
10 const int MaxN = 220;
11 
12 int N, arr[MaxN];
13 int dp[MaxN][MaxN] = {0};
14 
15 void Solve() {
16     int len = (N << 1);
17     for (int k = 1; k < len; ++k) {
18         for (int i = 0; (i + k) < len; ++i) {
19             for (int j = i; j < (i + k); ++j) {
20                 dp[i][i + k] = max(dp[i][i + k], dp[i][j] + dp[j + 1][i + k] + arr[i] * arr[j + 1] * arr[i + k + 1]);
21             }
22         }
23     }
24     int ans = 0;
25     for (int i = 0; i < N; ++i) {
26         ans = max(ans, dp[i][i + N - 1]);
27     }
28     cout << ans << endl;
29 }
30 
31 int main() {
32 
33     cin >> N;
34     for (int i = 0; i < N; ++i) {
35         cin >> arr[i];
36         arr[i + N] = arr[i];
37     }
38 
39     Solve();
40 
41 
42     
43 #ifdef HOME
44     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
45 #endif
46     return 0;
47 }
 
posted @ 2015-10-30 20:20  JmingS  阅读(216)  评论(0编辑  收藏  举报