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

 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.
View Code

 

posted on 2013-11-30 14:26  acphile  阅读(116)  评论(0)    收藏  举报