思想与合并果子相同。逆序地来想,显然这些板子必须一共切割n-1次,如何恰当的分配这n-1次切割就是关键所在。这里就用到了构造Huffman树的贪心思想。

即每次从待合并序列中取两个最小的值,将它们合并成一个较大的,然后把这个较大的在加入进待合并的序列当中,直到待合并序列中只有一个元素。而不加任何优化时复杂度为O(n^2),难以承受。

可以用堆将复杂度优化到O(nlogn),就完全可以接受了。

CODE

Program plank;//By_Thispoet
Const
	maxn=20000;
Var
	i,j,k,m,n,heap_size						:Longint;
	ans										:Int64;
	heap									:Array[1..maxn]of Longint;
	
Procedure Down(i:Longint);
var j:Longint;
begin
	while (i<<1)<=heap_size do
		begin
			j:=i<<1;
			if (heap[j+1]<heap[j])and(j<heap_size) then inc(j);
			if heap[j]<heap[i] then
				begin
					heap[i]:=heap[i] xor heap[j];
					heap[j]:=heap[i] xor heap[j];
					heap[i]:=heap[i] xor heap[j];
					i:=j;
				end else break;
		end;
end;


Procedure Up(i:Longint);
var j:Longint;
begin
	while i>1 do
		begin
			j:=i>>1;
			if heap[j]>heap[i] then
				begin
					heap[i]:=heap[i] xor heap[j];
					heap[j]:=heap[i] xor heap[j];
					heap[i]:=heap[i] xor heap[j];
					i:=j;
				end else break;
		end;
end;

	
BEGIN


	readln(heap_size);
	for i:=1 to heap_size do readln(heap[i]);
	for i:=heap_size >>1 downto 1 do Down(i);
	while heap_size>1 do
		begin
			k:=heap[1];
			heap[1]:=heap[heap_size]xor heap[1];
			heap[heap_size]:=heap[heap_size]xor heap[1];
			heap[1]:=heap[heap_size]xor heap[1];
			dec(heap_size);
			Down(1);
			inc(k,heap[1]);
			heap[1]:=heap[heap_size]xor heap[1];
			heap[heap_size]:=heap[heap_size]xor heap[1];
			heap[1]:=heap[heap_size]xor heap[1];
			dec(heap_size);
			Down(1);
			inc(heap_size);
			heap[heap_size]:=k;
			Up(heap_size);
			inc(ans,k);
		end;
	
	writeln(ans);
	
	
END.