乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
两个剪枝的方法:
1.中间加一个变量记录当前搜到的木棒的长度,由于数据是有序的,如果下一个和当前的相等,就不用搜了。
2.如果当前搜索的是从第一个木棒开始的,不需要回溯,直接搜下一层。因为第一个在这一次中一定要被用到的。
var a:array[0..100]of longint;
v:array[0..100]of boolean;
n,i,j,tot:longint;
procedure qsort(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=a[(l+r) shr 1];
repeat
while x<a[i] do inc(i);
while x>a[j] do dec(j);
if i<=j then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
function dfs(len,goal,rest,x:longint):boolean;
var t,i:longint;
begin
t:=0;
if rest=0 then exit(true);
if len=goal then exit(dfs(0,goal,rest-goal,1));
for i:=x to n do
if not v[i] then
begin
if len+a[i]>goal then continue;
if a[i]=t then continue;
v[i]:=true;
if dfs(len+a[i],goal,rest,i+1) then exit(true);
v[i]:=false;
t:=a[i];
if x=1 then break;
end;
exit(false);
end;
function work:longint;
var i:longint;
begin
for i:=n downto 1 do
begin
if tot mod i<>0 then continue;
if tot div i<a[1] then continue;
fillchar(v,sizeof(v),0);
v[1]:=true;
if dfs(a[1],tot div i,tot,2) then exit(tot div i);
end;
end;
begin
while true do
begin
fillchar(a,sizeof(a),0);
tot:=0;
readln(n);
if n=0 then break;
for i:=1 to n do
begin
read(a[i]);
tot:=tot+a[i];
end;
qsort(1,n);
writeln(work);
end;
end.