这个贴代码容易理解一点:

1 var a:array[0..100] of longint; 2 f:array[0..100] of boolean; 3 s,i,p,j,n,max,k:longint; 4 check:boolean; 5 function dfs(i,now,t:longint):boolean; //i当前用到了哪个木棒,now是拼接一根原木棒还差的长度,t为没用过的木棒总长度 6 var j:integer; 7 begin 8 if now=0 then 9 begin 10 t:=t-p; 11 if t=0 then exit(true); 12 j:=1; 13 while f[j] do j:=j+1; //完成了一根原木棒的拼接后,找一根最大且没用过的木棒进行下一组拼接。 14 f[j]:=true; 15 if dfs(j+1,p-a[j],t) then exit(true); 16 f[j]:=false; 17 t:=t+p; //回溯 18 end 19 else begin 20 for j:=i to n do 21 begin 22 if (j>1) and (a[j]=a[j-1]) and not f[j-1] then continue;//剪枝,两根相等的木棒,前一根不能完成后续拼接那后 一根显然也不行 23 if not f[j] and (now>=a[j]) then //满足条件才尝试 24 begin 25 now:=now-a[j]; 26 f[j]:=true; 27 if dfs(j,now,t) then exit(true); 28 now:=now+a[j]; //回溯 29 f[j]:=false; 30 if a[j]=now then break; // 此时后续尝试失败,所以当前状态不成立,直接返回一层(即使后面有和等于a[j]的 31 一根或几根木棒,使用a[j]后剩下的木棒拼接肯定比使用几根和等于a[j]的木棒剩下 32 的木棒拼接更灵活;使用木棒j不成立,显然后面的尝试也不成立,跳过! 33 end; 34 end; 35 end; 36 dfs:=false; //所有尝试都试过了,显然当前状态不成立; 37 end; 38 39 begin 40 readln(n); 41 while n<>0 do 42 begin 43 s:=0; 44 fillchar(a,sizeof(a),0); 45 max:=0; 46 for i:=1 to n do 47 begin 48 read(a[i]); 49 s:=s+a[i]; 50 if max<a[i] then max:=a[i]; 51 end; 52 sort(1,n); //从大到小快排省略; 53 readln; 54 for i:=n downto 1 do //穷举原来可能有几根 55 if (s mod i=0) and (s div i>=max) then //剪枝,原来长度一定是总长度的约数且不小于当前最长的小段 56 begin 57 fillchar(f,sizeof(f),false); 58 p:=s div i; 59 if dfs(1,p,s) then break; 60 end; 61 writeln(p); 62 readln(n); 63 end; 64 end.