[RQNOJ646]一道搜索神题

RQNOJ646

现在有N个元素,每个元素具有3个属性Ai, Bi, Ci,现在青青要求把全部元素分为3个集合,称为集合X、集合Y和集合Z,使表达式的值最小。
可以让某个集合为空。

1 ≤ n ≤ 100, 000,1 ≤ Ai, Bi, Ci ≤ 100, 000, 000

怎么说呢?

这题是我至今见到过的最神奇的一题。神奇到叹为观止。

经尝试,贪心是不行的,易找出反例。

经尝试,高深的算法和数据结构是很难想出来和写出来的。

经了解,本题可以用搜索做。且必须是裸搜,即O(3^N)的。

经尝试,若加个排序的预处理,写O(NlogN+2^N)是过不了的。

对于O(3^(10^5))在1s内跑出,我实在无话可讲。

这就是:只有想不到,没有做不到。

var
	a,b,c:array[1..1000000] of longint;
	n,i,j,k,l,p,min:longint;
procedure search(i,s1,s2,s3:longint);
begin
	if s1+s2+s3>=min then exit;
	if i<=n then
		        if (a[i]<=s1)or(b[i]<=s2)or(c[i]<=s3) then search(i+1,s1,s2,s3)
		        else
		        begin
                                if a[i]>s1 then search(i+1,a[i],s2,s3);
                                if b[i]>s2 then search(i+1,s1,b[i],s3);
		                if c[i]>s3 then search(i+1,s1,s2,c[i]);
		        end
        else min:=s1+s2+s3;
end;
begin
	readln(n);
	for i:=1 to n do readln(a[i],b[i],c[i]);
	min:=100000000;
	search(1,0,0,0);
	writeln(min);

end.
原文地址:https://www.cnblogs.com/oldmanren/p/2220691.html