石子合并问题--直线版
Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HRBUST. Original ID: 1818
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
1 #include <iostream> 2 #include <cstdio> 3 #define INF 0x3f3f3f3f 4 using namespace std; 5 const int maxn = 300; 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 maxS[i][i] = minS[i][i] = 0; 13 sum[i] += sum[i-1]; 14 } 15 for(int j = 2; j <= n; ++j){ 16 for(int i = 1; i+j-1 <= n; ++i){ 17 int t = i+j-1,tmp = sum[t] - sum[i-1]; 18 maxS[i][t] = -INF; 19 minS[i][t] = INF; 20 for(int k = i; k < t; ++k){ 21 minS[i][t] = min(minS[i][t],minS[i][k]+minS[k+1][t]+tmp); 22 maxS[i][t] = max(maxS[i][t],maxS[i][k]+maxS[k+1][t]+tmp); 23 } 24 } 25 } 26 printf("%d %d\n",minS[1][n],maxS[1][n]); 27 } 28 return 0; 29 }
时间: 2024-12-30 19:20:48