洛谷P1880 石子合并

经典水题.......

断环为链长度乘二,求前缀和区间DP。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define int long long
 5 const int N = 210;
 6 
 7 int f[N][N], sum[N];
 8 
 9 main() {
10     int n;
11     scanf("%lld", &n);
12     for(int i = 1; i <= n; i++) {
13         scanf("%lld", &sum[i]);
14         sum[n + i] = sum[i];
15     }
16     memset(f, 0x3f, sizeof(f));
17     for(int i = 1; i <= n << 1; i++) {
18         sum[i] += sum[i - 1];
19         f[i][i] = 0;
20     }
21 
22 
23     for(int len = 2; len <= n; len++) {
24         for(int l = 1; l + len - 1 <= n << 1; l++) {
25             int r = l + len - 1;
26             for(int k = l; k < r; k++) {
27                 f[l][r] = std::min(f[l][r], f[l][k] + f[k + 1][r] + sum[r] - sum[l - 1]);
28             }
29         }
30     }
31 
32     int ans = 0x3f3f3f3f3f3f3f3f;
33     for(int i = 1; i <= n; i++) {
34         ans = std::min(ans, f[i][i + n - 1]);
35     }
36     printf("%lld\n", ans);
37 
38     memset(f, 0, sizeof(f));
39     for(int len = 2; len <= n; len++) {
40         for(int l = 1; l + len - 1 <= n << 1; l++) {
41             int r = l + len - 1;
42             for(int k = l; k < r; k++) {
43                 f[l][r] = std::max(f[l][r], f[l][k] + f[k + 1][r] + sum[r] - sum[l - 1]);
44             }
45         }
46     }
47     ans = 0;
48     for(int i = 1; i <= n; i++) {
49         ans = std::max(ans, f[i][i + n - 1]);
50     }
51     printf("%lld", ans);
52     return 0;
53 }
AC代码

这里用了个define int long long的骚操作,不推荐,可能爆0。

posted @ 2018-09-06 20:59  huyufeifei  阅读(121)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜