POJ2454 Jersey Politics ——贪心+随机化算法

 初看此题时,显然大家都想到了贪心+搜索+剪枝,但是POJ的评测机是很不给力的,一定是TLE。所以,理所当然的,我们知道了random的威力。

先证明一下贪心算法的正确性:

策略:将这n*3个元素倒序快排一下,取前n*2个元素分为两组,最后n个元素分为一组。

证明:如果不这样选的话,那么前两组的总和必会比这样选的情况小,那么更有可能失败。证毕。

随机化算法:

每次从前两个集合中各选一个元素进行交换,如果满足条件直接输出并halt.

这个随机化的证明嘛,我也不会。

CODE

Program POJ2454;//By_Poetshy
Const
	maxn=200;
Var
	i,j,k,m,n					:Longint;
	a,rank						:Array[1..maxn]of Longint;
	v							:Array[1..maxn]of Boolean;
	all,sum,temp				:Longint;

Procedure Qsort(l,r:Longint);
var i,j,k,temp:Longint;
begin
	i:=l;j:=r;k:=a[(i+j)>>1];
	repeat
		while a[i]>k do inc(i);
		while a[j]<k do dec(j);
		if i<=j then
			begin
				temp:=a[i];a[i]:=a[j];a[j]:=temp;
				temp:=rank[i];rank[i]:=rank[j];rank[j]:=temp;
				inc(i);dec(j);
			end;
	until i>j;
	if i<r then Qsort(i,r);
	if l<j then Qsort(l,j);
end;

Procedure Print;
var j:Longint;
begin
	for j:=1 to n do writeln(rank[j]);
	for j:=n+1 to n*2 do writeln(rank[j]);
	for j:=n*2+1 to n*3 do writeln(rank[j]);
end;

Function check:Boolean;
begin
	if sum<=500*n then exit(false);
	if all-sum<=500*n then exit(false);
	exit(true);
end;

BEGIN
	readln(n);
	for i:=1 to n*3 do
		begin
			readln(a[i]);rank[i]:=i;
		end;
	Qsort(1,n*3);
	sum:=0;m:=1;
	fillchar(v,sizeof(v),0);
	for i:=1 to n<<1 do inc(all,a[i]);
	for i:=1 to n do 
		begin
			inc(sum,a[i]);
			v[i]:=true;
		end;
	randomize;
	while true do 
		begin
			if Check then 
				begin
					Print;
					halt;
				end;
			i:=random(n)+1;
			j:=random(n)+n+1;
			inc(sum,a[j]);dec(sum,a[i]);
			temp:=a[i];a[i]:=a[j];a[j]:=temp;
			temp:=rank[i];rank[i]:=rank[j];rank[j]:=temp;
		end;
END.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值