石子合并问题
Time Limit:1000MS Memory Limit:65536K
Total Submit:135 Accepted:54
Description
在一个圆形操场的四周摆放着n 堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
编程任务:
对于给定n堆石子,编程计算合并成一堆的最小得分和最大得分。
Input
输入包括多组测试数据,每组测试数据包括两行。
第1 行是正整数n,1<=n<=100,表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。
Output
对于每组输入数据,输出两行。
第1 行中的数是最小得分;第2 行中的数是最大得分。
Sample Input
4
4 4 5 9
Sample Output
43
54
Source
elba
var
f,ff,b:array[0..200,0..200]of longint;//f[i,j]为第i堆到第j堆的最小值,ff[i,j]则反之
a:array[0..200]of longint;
n,i,j,k,minn,maxn:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
function min(a,b:longint):longint;
begin
if a<b then exit(a);
exit(b);
end;
begin
read(n);
for i:=1 to n do
begin
read(a[i]);
a[i+n]:=a[i];//转换成2n的数列
end;
for i:=1 to n*2 do
for j:=1 to n*2 do
for k:=i to j do
b[i,j]:=b[i,j]+a[k];//统计从i合并到j共需要的代价
fillchar(f,sizeof(f),$7F);
for i:=1 to n*2 do f[i,i]:=0;//自己合并到自己不用代价
for i:=2 to n do//一份中有多少个石子
for j:=1 to n*2-i+1 do//需要合并的个数
for k:=j+1 to j+i-1 do//枚举
begin
f[j,j+i-1]:=min(f[j,j+i-1],f[j,k-1]+f[k,j+i-1]+b[j,j+i-1]);
ff[j,j+i-1]:=max(ff[j,j+i-1],ff[j,k-1]+ff[k,j+i-1]+b[j,j+i-1]);
end;
minn:=23333333;
for i:=1 to n do
begin
minn:=min(minn,f[i,i+n-1]);
maxn:=max(maxn,ff[i,i+n-1]);
end;
writeln(minn);
writeln(maxn);
end.