poj 1011

题目大意:给出一些长度不大于 50 的木棍, 要求你把这些小木棍拼成

             长度相同木棍,当然长度越小越好。

剪枝:

1.最长的木棍的长度一定不会超过以前的木棍长度,所以从最长的长度开始枚举

2.如果总长度不能被选中的长度整除剪掉

3.如果所求木棍数等于总长度除以所枚举的木棍长度返回,不要再向下搜索

4.每加入一个木棍做一下标记,以免被再次搜索

5.从大到小排序,这样如果当前的不能被加入,太大了,只要往后搜小的就行 

6.如果向下搜索失败回退回来,下一根木块与当前这根碎木块长度相同,则不需要对他进行搜索了,直接跳过

自己写的超时代码,水平不够,继续努力

 1 import java.util.Arrays;
 2 import java.io.BufferedReader;
 3 import java.io.InputStreamReader;
 4 import java.util.StringTokenizer;
 5 
 6 public class Main{
 7     static int lens[];
 8     static boolean visit[];
 9     
10     public static boolean dfs(int len,int cur,int index,int cnt,int j,int n){ // len目标长度,cur当前木棍的长度,index木棍的下标,                                                         
11         if(cnt == j){                                                         //cnt已经拼成的目标木棍数量,j总共需拼成的目标木棍的数量
12             return true;
13         }                                         
14         else if(len == cur){    
15             return dfs(len,0,0,cnt+1,j,n);
16         }
17             
18         else{
19             int i;
20             int sample = -1;
21             for(i=index;i<n;i++){
22                 if(visit[i]==false && lens[i]!=sample && cur +lens[i]<=len){
23                     visit[i]=true;
24                     if(dfs(len,cur+lens[i],i+1,cnt,j,n)){
25                         return true;
26                     }
27                     sample = lens[i];
28                     visit[i] = false;
29                 }
30                 if(len==0)
31                     break;
32             }
33             return false;
34         }
35     }
36     
37     public static void main(String[] args) throws Exception{
38         int n;
39         BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
40         while((n = Integer.parseInt(bf.readLine())) != 0){
41             StringTokenizer take = new StringTokenizer(bf.readLine());
42             lens = new int[n];
43             visit = new boolean[n];
44             
45             int index = 0;
46             int result = 0;
47             while (take.hasMoreTokens()) {
48                  lens[index] = Integer.parseInt(take.nextToken());
49                  result += lens[index++];
50             }
51             
52             Arrays.sort(lens);
53             for(int len=lens[n-1];len<=result;len++){
54                 if(result%len!=0)           //剪枝,原始木棍长度必须能整除所有木棍长度和
55                     continue;
56                 int j = result/len;
57                 if(dfs(len,0,0,0,j,n)){
58                     System.out.println(len);
59                     break;
60                 }    
61             }
62         }
63     }
64 }

 

posted @ 2015-05-06 15:18  杨永华  阅读(155)  评论(0编辑  收藏  举报