HRBUST 1818 石子合并问题--直线版

石子合并问题--直线版

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-08-02 10:28:15

HRBUST 1818 石子合并问题--直线版的相关文章

brbustoj 1818 石子合并问题--直线版

比较经典且基础的区间dp,转移方程为 dp_max[i][j] = max(dp_max[i][j],dp_max[i][k] + dp_max[k+1][j] + sum[j]-sum[i-1]); dp_min[i][j] = min(dp_min[i][j],dp_min[i][k] + dp_min[k+1][j] + sum[j]-sum[i-1]); #include <fstream> #include <iostream> #include <cstdio&g

动态规划—石子合并(直线和环)

先来看直线的: N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24) 1 2 3 4 => 1 2 7(7) => 3 7(10) =>

石子合并问题(直线版)

首先来个题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=737 有个更难的版本(不过很好玩):http://www.lydsy.com/JudgeOnline/problem.php?id=3229 题目: 石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价

直线石子合并(区间DP)

石子合并 时间限制:1000 ms  |  内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值和最大值. 输入有多组测试数据,输入到文件结束.每组测试数据第一行有一个整数n,表示有n堆石子.接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 输出输出总代价的最小值以及最大值(中间以空格隔开)

(转)石子合并问题

本文转自 http://blog.csdn.net/acdreamers/article/details/18039073 石子合并问题是最经典的DP问题.首先它有如下3种题型:   (1)有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为新合成的一堆石子的数量.求将这N堆石子合并成一堆的总花费最小(或最大). 分析:当然这种情况是最简单的情况,合并的是任意两堆,直接贪心即可,每次选择最小的两堆合并.本问题实际上就是哈夫曼的变形.     (2)有N堆石

[08山东省选]2298 石子合并

2298 石子合并 2008年省队选拔赛山东 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石子合并成一堆的最小得分. 输入描述 Input Description 第一行是一个数N. 以下N行每行一个数A,表示石子数目. 输出描述 O

算法温习动态规划之石子合并问题

石子合并问题分为直线型和圆形: 直线型: 直线型狮子合并问题存在以下递推式: f[i][j]:表示从第i堆合并到底j堆,最少代价 f[i][j]=0;     i=j f[i][j]=min( f[i][k]+f[k+1][j]+sum(i,j));       i<=k<j; 这个问题比较好理解,根据递推式,我们的i要从高到底遍历,j要从低到高遍历 直线型代码如下: #include<iostream> #include<vector> using namespace

HDU 3506 (环形石子合并)区间dp+四边形优化

Monkey Party Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 1699    Accepted Submission(s): 769 Problem Description Far away from our world, there is a banana forest. And many lovely monkeys l

BZOJ 3229: [Sdoi2008]石子合并

3229: [Sdoi2008]石子合并 时间限制: 3 Sec  内存限制: 128 MB提交: 497  解决: 240[提交][][] 题目描述 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石子合并成一堆的最小得分. 输入 第一行是一个数N. 以下N行每行一个数A,表示石子数目. 输出 共一个数,即N堆石子合并成一堆的最小得分. 样例输入 4 1 1 1 1 样