DP地狱训练 石子合并

1270: [DP地狱训练]石子合并

时间限制: 1 Sec  内存限制: 64 MB
提交: 1004  解决: 204
[提交][状态][讨论版]

题目描述

有n堆石子围成一个圆圈。现在需要把它们合并成一堆石子。每次合并时,只能合并相邻的两堆石子,所耗力气为两堆石子重量之和,合并得到的新堆的重量为原两堆重量之和。问最少需要耗费多少力气? 数据规模:1<=n<=200,合并n堆石子最少需要耗费的力气不超过2*10^9。

输入

第一行一个整数n,第二行n个整数,表示顺序排列的每堆石子的重量。

输出

只有一行,该行只有一个整数,表示合并这n堆石子最少需要耗费的力气。

样例输入

3
1 3 5

样例输出


 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <vector>
 7  
 8 using namespace std;
 9  
10 #define INF 500000000000LL
11  
12 long long n, a[700], f[700][700], ans = INF;
13  
14 int main(){
15     scanf("%lld", &n);
16     for(int i = 1 ; i <= n ; i ++){
17         scanf("%lld", &a[i]);
18         a[n + i] = a[i];
19     }
20     n *= 2;
21     for(int i = 1 ; i <= n ; i ++)for(int j = 1 ; j <= n ; j ++)f[i][j] = INF;
22     for(int i = 1 ; i <= n ; i ++){
23         a[i] += a[i - 1];
24         f[i][i] = 0;
25     }
26     for(int len = 2 ; len <= n ; len ++){
27         for(int i = 1, j ; i + len - 1 <= n ; i ++){
28             j = i + len - 1;
29             for(int k = i ; k < j ; k ++){
30                 f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + a[j] - a[i - 1]);
31             }
32         }
33     }
34     for(int i = 1 ; i <= n / 2 ; i ++)
35         ans = min(ans, f[i][i + n / 2 - 1]);
36     printf("%lld\n", ans);
37 }
View Code

 


posted @ 2017-08-08 15:48  KingSann  阅读(308)  评论(0编辑  收藏  举报