AcWing 167. 木棒
DFS剪枝,具体过程看代码内部,另外排序也算剪枝的一部分
#include<bits/stdc++.h>
using namespace std;
const int N = 70;
int n;
int sum;
int len;
int w[N];
bool st[N];
bool dfs(int t, int l, int start){ //分别表示第t根大棍,当前大棍长度为l,从第start根小棍开始算
if(t * len == sum) return true;
if(l == len) return dfs(t + 1, 0, 0);
for(int i = start; i < n; i ++ ){
if(st[i] || l + w[i] > len) continue;
st[i] = true;
if(dfs(t, l + w[i], start + 1)) return true;
st[i] = false; //到这里表明这小棍不能用
//截至目前已经表明这根小棍没法得到正确答案,以下都是剪枝
//剪枝操作
//1.
//如果l == 0表示当前大棍的长度长度无法得到正确答案,就剪枝
//如果l + w[i] == len表示当前大棍的长度无法得到正确答案,就剪枝
if(!l || l + w[i] == len) return false;
//2.如果当前w[i]不合适,那么所有和w[i]等长的小棍都不合适,全部跳过
int j = i;
while(j < n && w[i] == w[j]) j ++ ;
i = j - 1;
}
return false;
}
int main()
{
while(cin>>n){
if(!n) break;
memset(st, 0, sizeof st);
sum = 0;
for(int i = 0; i < n ; i ++ ){
cin>>w[i];
sum += w[i];
}
//剪枝操作,大的木棍放前面可以减少搜索的情况
sort(w, w + n);
reverse(w, w + n);
len = 1;
while(true){
if(sum % len == 0 && dfs(0, 0, 0)){
cout<<len<<endl;
break;
}
else len ++ ;
}
}
return 0;
}