Java-POJ1011-sticks

很经典的搜索题,直接爆搜会卡在连续相同长度的木棍,可以先排序,预处理该长度不行直接跳下一长度木棍的位置

但此题特殊,木棍长度小于50,我们可以直接桶排序

还有就是关于回溯的理解:

我们写的dfs为的是判断ans是否可行,可行解自然已经被记录下来了,并且一路return即,若回溯到了相同or类似情况,说明必定不能符合题意

TIPS:桶排序+可行性剪枝

 1 package poj.ProblemSet;
 2 
 3 import java.util.Scanner;
 4 
 5 public class poj1011 {
 6     public static final int MAXN = 100;
 7     public static int[] bucket = new int[MAXN];
 8     public static int  ans, flag, sum, maxn, minn;
 9 
10     public static void dfs(int res, int sum, int p) {
11         if (res == 0||flag==1) { flag = 1;return; }
12         if (sum == ans) { dfs(res - 1, 0, maxn);return;}
13         for (int i = p; i >= minn; i--) {
14             if (bucket[i]>0 && i + sum <= ans) {
15                 bucket[i]--;
16                 dfs(res, sum + i, i);//(*)
17                 bucket[i]++;
18                 if (sum == 0 || sum + i == ans) break;
19                 //执行此句说明(*)行尝试失败,因此到达当前情况的搜索均可剪枝
20             }
21         }
22     }
23 
24     public static void main(String[] args) {
25         Scanner cin = new Scanner(System.in);
26         for (int n = cin.nextInt(); n != 0; n = cin.nextInt()) {
27             sum = flag = maxn = 0;minn = MAXN;
28             for (int i = 0; i < MAXN; i++) bucket[i] = 0;
29             for(int i=1;i<=n;i++) {
30                 int temp = cin.nextInt();
31                 bucket[temp]++;
32                 sum += temp;
33                 maxn = Math.max(maxn, temp);
34                 minn = Math.min(minn, temp);
35             }
36             int INF = sum / 2;
37             for (int i = maxn; i <= INF; i++)
38                 if (sum % i == 0) {
39                     ans = i;
40                     dfs(sum / i, 0, maxn);
41                     if(flag==1)break;
42                 }
43             if (flag == 1) System.out.println(ans);
44             else System.out.println(sum);
45         }
46     }
47 }

 

posted @ 2020-01-30 15:31  墨鳌  阅读(281)  评论(0编辑  收藏  举报