hihocoder1636 Pangu and Stones

思路:

区间dp。dp[l][r][k]表示把区间[l, r]的石子合并成k堆所需要的最小代价。

实现:

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int INF = 0x3f3f3f3f;
 6 const int N = 105;
 7 
 8 int a[N], sum[N], dp[N][N][N];
 9 int n, L, R;
10 
11 int dfs(int l, int r, int k)
12 {
13     if (l == r) return k == 1 ? 0 : INF;
14     if (r - l + 1 == k) return 0;
15     if (dp[l][r][k] != -1) return dp[l][r][k];
16     int ans = INF;
17     if (k == 1)
18     {
19         for (int i = L; i <= R; i++)
20             ans = min(ans, dfs(l, r, i) + sum[r] - sum[l - 1]);
21     }
22     else
23     {
24         for (int i = 0; i < r - l; i++)
25             ans = min(ans, dfs(l, l + i, 1) + dfs(l + i + 1, r, k - 1));
26     }
27     return dp[l][r][k] = ans;
28 }
29 
30 int main()
31 {
32     while (cin >> n >> L >> R)
33     {
34         memset(sum, 0, sizeof sum);
35         memset(dp, -1, sizeof dp);
36         for (int i = 1; i <= n; i++)
37         {
38             cin >> a[i];
39             sum[i] = sum[i - 1] + a[i];
40         }
41         int ans = dfs(1, n, 1);
42         cout << (ans == INF ? 0 : ans) << endl;
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/wangyiming/p/9865672.html