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

题目描述 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<f2[i,i+n-1]
then maxx:=f2[i,i+n-1];
writeln(minx);
writeln(maxx);
end.
原文地址:https://www.cnblogs.com/spiderKK/p/4278391.html