题目描述 Description
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
标签:
4
4 5 9 4
43
54
来源:NOI 1996
代码:
var n,i,j,k,l,minf,maxf:longint;
a,s:array[0..300] of longint;
f:array[1..300,1..300] of longint;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
begin
readln(n);
for i:=1 to n do
begin
read(a[i]);
a[i+n]:=a[i];
end;
for i:=1 to 2*n-1 do
s[i]:=s[i-1]+a[i];
for l:=2 to n do //枚举可能的长度
for i:=1 to 2*n-l do //环形扩展到链
begin
j:=i+l-1;
f[i,j]:=maxlongint;
for k:=i to j-1 do
f[i,j]:=min(f[i,j], f[i,k]+f[k+1,j]+s[j]-s[i-1]);
end;
minf:=maxlongint;
for i:=1 to n do minf:=min(minf,f[i,i+n-1]); //求出最小的值
fillchar(f,sizeof(f),0);
for l:=2 to n do
for i:=1 to 2*n-1 do
begin
j:=i+l-1;
f[i,j]:=0;
for k:=i to j-1 do
f[i,j]:=max(f[i,j], f[i,k]+f[k+1,j]+s[j]-s[i-1]);
end;
maxf:=0;
for i:=1 to n do maxf:=max(maxf,f[i,i+n-1]);
writeln(minf);
writeln(maxf);
end.
标签:
原文地址:http://www.cnblogs.com/zqzxwdm/p/4739983.html