HRBUST 1819 石子合并问题--圆形版

石子合并问题--圆形版

Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HRBUST. Original ID: 1819
64-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\n",minAns,maxAns);

35     }

36     return 0;

37 }
View Code
 
   

 

 

你可能感兴趣的:(问题)