很经典的搜索题,直接爆搜会卡在连续相同长度的木棍,可以先排序,预处理该长度不行直接跳下一长度木棍的位置
但此题特殊,木棍长度小于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 }