AcWing 167. 木棒
原题链接
中等
作者:
季之秋
,
2021-04-09 08:41:51
,
所有人可见
,
阅读 263
/*
(1) 优先dfs选择性小的路径(逆序排序)
(2) 沉余性剪枝,考虑每层顺序循环,减去重复部分,组合枚举(存每层start)
(3) 可行性剪枝,什么情况失败了这个方案就失败了,
1.重复长度是多余的
2.第一根失败或者最后一根失败代表整个方案失败
3.总数刚好等于长度再递归下一层,否则该层都凑不出来
*/
import java.util.*;
public class Main{
static int N = 70, n;
static Integer a[] = new Integer[N];
static boolean st[] = new boolean[N];
static int sum, length;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(true){
n = sc.nextInt();
if(n == 0) break;
Arrays.fill(st, false);
sum = 0;
for(int i = 0; i < n ; i ++){
a[i] = sc.nextInt();
sum += a[i];
}
Arrays.sort(a, 0, n, Collections.reverseOrder());
length = 1;
while(true){
if(sum % length == 0 && dfs(0, 0, 0)){
System.out.println(length);
break;
}
length++;
}
}
}
static boolean dfs(int u ,int s, int start){
if(u * length == sum) return true;
if(s == length) return dfs(u+1, 0, 0);
for(int i = start; i < n ; i ++){
if(st[i]) continue;
if(s + a[i] > length) continue;
st[i] = true;
if(dfs(u, s + a[i], i + 1)) return true;
st[i] = false;
if(s == 0) return false;
if(s + a[i] == length) return false;
int j = i;
while(j < n && a[j] == a[i]) j ++;
i = j -1;
}
return false;
}
}