问题描述
有n堆果子,现要将n堆果子合并成一堆,每次合并要的体力为两堆果子的值。现要求用最小体力合并果子。
输入
3
1 2 9
输出
15
算法讨论
因为要求每次合并的体力最小,那我们可以将它排序,但数据过大会超时,所以我们可以构建哈夫曼树,每次构建插入后再用堆排序维护就好。
const
maxn=10000;
var
a:array[1..maxn] of longint;
i,j,n,m,s,t:longint;
procedure siftdown(i,n:longint);
var
j,t:longint;
begin
j:=i*2;
while j<=n do
begin
if j<n
then if a[j]>a[j+1]
then j:=j+1;
if a[i]>a[j]
then begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
i:=j;
j:=i*2
end
else break
end;
end;
begin
read(n);
for i:=1 to n do
read(a[i]);
for i:=n div 2 downto 1 do
siftdown(i,n);
m:=n;
for i:=1 to n-2 do
begin
t:=a[1]; a[1]:=a[m]; a[m]:=t;
siftdown(1,m-1);
a[1]:=a[1]+a[m];
s:=s+a[1];
m:=m-1;
siftdown(1,m)
end;
s:=s+a[1]+a[2];
write(s)
end.
Pixiv ID:61577957