题目: | 合并果子 | |
来源: | Noip2004T2 | |
题目大意: | N个数,通过n-1次合并将其合并为一个数,把每次合并的两个数的和加在一起即为 要求的数,要求其最小 | |
数据范围: | 1 <= n <= 10000 | |
样例: | 3 1 2 9 | 15 |
做题思路: | 如果想最小,就要每次取得的都最小,每次去最小不就是小根堆嘛。 | |
知识点: | 堆 |
var
a:array[0..10010]of longint;
tot,n,ans:longint;
procedure ad_up(x:longint);
var
i,t:longint;
begin
whilex div 2>=1 do
begin
i:=xdiv 2;
ifa[i]>a[x] then
begin
t:=a[i];a[i]:=a[x];a[x]:=t;
x:=i;
end
elseexit;
end;
end;
procedure ad_down(x:longint);
var
i,t:longint;
begin
whilex*2<=tot do
begin
i:=x*2;
ifa[i]>a[i+1] then inc(i);
ifa[i]<a[x] then
begin
t:=a[i];a[i]:=a[x];a[x]:=t;
x:=i;
end
elseexit;
end;
end;
procedure init;
var
i:longint;
begin
readln(n);
fori:=1 to n do
begin
inc(tot);
read(a[tot]);
ad_up(tot);
end;
end;
procedure main;
var
i,x:longint;
begin
fori:=1 to n-1 do
begin
x:=a[1];
a[1]:=a[tot];
dec(tot);
ad_down(1);
x:=x+a[1];
ans:=ans+x;
a[1]:=a[tot];
dec(tot);
ad_down(1);
inc(tot);
a[tot]:=x;
ad_up(tot);
end;
end;
begin
init;
main;
writeln(ans);
end.
题目来源:
http://yuanti.tyvj.cn:8080/Problem_Show.asp?id=1047