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 }