POJ3253 Fence Repair ——贪心(Huffman树的构造)+堆——Pku3253

思想与合并果子相同。逆序地来想,显然这些板子必须一共切割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.

你可能感兴趣的:(Huffman)