一道恶心的题目 poj1011小木棍

 

1.        题目 poj 1011

Description

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

Input

输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

Output

为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

Sample Input

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample Output

6
5

Source

Central Europe 1995

 

这道题目做了很久,许多人都是tle的,我居然交了很多次wa,后来发现居然是个很xx的错误(代码中后面加上了fuck的那个),改完后还是tle,后来加上了一个most powerful(这个优化是很强大的:如果每个包装了第一个没有搜到可行解,装其他的也不可行,直接退出,重新装前一个包),剪枝后就0ms ac了。

var f,a:array[0..3000] of longint;
v:array[0..3000] of boolean;
right:boolean;
n,m,k,sum:longint;
procedure qsort(l,r:longint);
var i,j,k,x:longint;
begin
 i:=l; j:=r; x:=a[(l+r) div 2];
 repeat
  while a[i]x do dec(j);
  if i<=j then
   begin
    k:=a[i]; a[i]:=a[j]; a[j]:=k;
    inc(i); dec(j);
   end;
 until i>j;
 if ia[i] then begin dfs(now,len-a[i],i-1);
       if not right then exit; v[i]:=false;//fuck2!!
       if len=m then exit;{most powerful} end
     else begin dfs(now-1,m,n-1); v[i]:=false;//fuck!
     exit;
     if not right then exit;
     end;
    {v[i]:=false;}
   end;
  {else if a[i]>len then
   exit;}
end;
begin
 {assign(input,'stick.in'); assign(output,'stick.out');
 reset(input); rewrite(output);}
 readln(n);
 while n<>0 do
  begin
   sum:=0;
 fillchar(a,sizeof(a),0);{fuck3!!}
 for m:=1 to n do
 begin
  read(k);
  if k<=50 then
   begin
    inc(a[0]); a[a[0]]:=k;
    inc(sum,a[a[0]]);
   end;
 end;
 n:=a[0];
 qsort(1,n);
 {for m:=1 to n do
  writeln(a[m]);}
 right:=true;
 for m:=a[n] to sum div 2 do
 if (sum mod m=0) and right then
  begin
   fillchar(v,sizeof(v),0);
   v[n]:=true;
   k:=sum div m;
   if a[n]=m then dfs(k-2,m,n-1)
   else dfs(k-1,m-a[n],n-1);
  end;
  if right then writeln(sum);
  readln(n);
 end;
 {close(input); close(output);}
end.


 

你可能感兴趣的:(S!,恶心的题目,搜索)