石子合并问题--圆形版
Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HRBUST. Original ID: 181964-bit integer IO format: %lld Java class name: Main
在圆形操场上摆放着一行共n堆的石子。现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请编辑计算出将n堆石子合并成一堆的最小得分和将n堆石子合并成一堆的最大得分。
Input
输入有多组测试数据。
每组第一行为n(n<=100),表示有n堆石子,。
二行为n个用空格隔开的整数,依次表示这n堆石子的石子数量ai(0<ai<=100)
Output
每组测试数据输出有一行。输出将n堆石子合并成一堆的最小得分和将n堆石子合并成一堆的最大得分。 中间用空格分开。
Sample Input
3
1 2 3
Sample Output
9 11
解题:还是区间型dp,其实跟直线版的没什么区别,只要把原来的数组复制一份加到后面,求2n长度的。。。
1 #include <iostream> 2 #include <cstdio> 3 #define INF 0x3f3f3f3f 4 using namespace std; 5 const int maxn = 400; 6 int maxS[maxn][maxn],minS[maxn][maxn],sum[maxn]; 7 int main(){ 8 int n; 9 while(~scanf("%d",&n)){ 10 for(int i = 1; i <= n; ++i){ 11 scanf("%d",sum+i); 12 sum[i+n] = sum[i]; 13 sum[i] += sum[i-1]; 14 } 15 for(int i = 1; i <= n; ++i) 16 sum[i+n] += sum[i+n-1]; 17 int m = n<<1,maxAns = -INF,minAns = INF; 18 for(int j = 2; j <= n; ++j){ 19 for(int i = 1; i + j - 1 <= m; ++i){ 20 int t = i + j - 1; 21 int tmp = sum[t] - sum[i-1]; 22 minS[i][t] = INF; 23 maxS[i][t] = -INF; 24 for(int k = i; k < t; ++k){ 25 minS[i][t] = min(minS[i][t],minS[i][k]+minS[k+1][t]+tmp); 26 maxS[i][t] = max(maxS[i][t],maxS[i][k]+maxS[k+1][t]+tmp); 27 } 28 } 29 } 30 for(int i = 1; i <= n; ++i){ 31 minAns = min(minAns,minS[i][i+n-1]); 32 maxAns = max(maxAns,maxS[i][i+n-1]); 33 } 34 printf("%d %d ",minAns,maxAns); 35 } 36 return 0; 37 }