石子归并-2:区间DP{环形}

题目描述 Description
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入描述 Input Description
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

输出描述 Output Description
输出共2行,第1行为最小得分,第2行为最大得分.

样例输入 Sample Input
4
4 4 5 9

样例输出 Sample Output
43
54

这道题和石子归并1一样,转移方程为f[i,j]:=f[i,k-1]+f[k,j]+sum[i,j];
但由于这道题是环形的,所以与石子归并1也有不同,
可以将数组扩展,求从1~n,2~n+1,...,n~2*n-1的最小得分,再从中取最小值。
最大值方法相同。
代码
var stone:array[1..200]of longint;
sum,f:array[0..200,1..200]of longint;
f2:array[0..200,1..200]of longint;
max,maxx:longint;
minx,h,min:longint;
i,j,k,l,n:longint;

begin readln(n);
for i:=1 to n do
read(stone[i]);
for i:=1 to n-1 do
stone[i+n]:=stone[i];

fillchar(sum,sizeof(sum),0);
for i:=1 to 2*n-1 do
begin sum[i,i]:=stone[i];
for j:=i+1 to i+n-1 do
sum[i,j]:=sum[i,j-1]+stone[j];
end;

for i:=1 to n do
begin for j:=i+n-1-1 downto i do
for k:=j+1 to i+n-1 do
begin min:=maxlongint;
max:=0;
for l:=j+1 to k do
begin if f[j,l-1]+f[l,k]+sum[j,k]max
then max:=f2[j,l-1]+f2[l,k]+sum[j,k];
end;
f[j,k]:=min;
f2[j,k]:=max;
end;
end;

minx:=maxlongint;
for i:=1 to n do
begin
if minx>f[i,i+n-1]
then minx:=f[i,i+n-1];
end;
maxx:=0;
for i:=1 to n do
if maxx石子归并-2:区间DP{环形}

时间: 2024-10-17 02:19:14

石子归并-2:区间DP{环形}的相关文章

51Nod - 1021 石子归并(区间DP)

[题目描述] 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) => 1

石子归并(codevs_1048)——区间dp

很经典的一道区间dp题. 突然觉得数据那么小,好像可以随便乱搞. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar()

codevs——1048 石子归并 (区间DP)

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn  (wi <= 100) 输出描述 Output Descriptio

石子归并(区间DP)

-->测评传送门 题目描述 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn (wi <= 100) 输出描述 一个整数表示最小合并代价 样例输入 4 4 1 1 4 样例输出 18 当时第一次学DP的一个坎儿,现在DP重现,终于弄会了QWQ 解析: 第一次学长讲的时候说要

石子合并(区间dp)

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

zjnu 1181 石子合并(区间DP)

Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合并前对调一次相邻两堆石子的次序. 计算在上述条件下将n堆石子合并成一堆的最小得分. Input 输入数据共有二行,其中,第1行是石子堆数n≤100: 第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔. Output 输出合并的最小得分. Sample Input 3 2 5 1 Sample Out

nyoj 737 石子合并(区间DP)

737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No通过数:28 提交数:35 难度:3 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. 输入描述: 有多组测试数据,输入到文件结束. 每组测试数据第一行有一个整数n,表示有n堆石子. 接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空

CH5301 石子合并【区间dp】

5301 石子合并 0x50「动态规划」例题 描述 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为 1  3  5  2 我们可以先合并1.2堆,代价为4,得到4 5 2 又合并 1,2堆,代价为9,得到9 2 ,再合并得到11,总代价为

直线石子合并(区间DP)

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