木棍
根据别人的代码改写的,大体思路没变,主要是剪枝的思想。
//用scanf防止超时
//剪枝 + dfs
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool cmp(int a, int b){
return a>b;
}
int sticks[70], used[70];
int length,cntt;
int n;
//dep 已经拼接好的木棍数
//conLen 已经拼好的长度
//pos 当前的位置
bool dfs(int dep, int conLen, int pos){
if(dep == cntt) return true; //木棍数量一致 直接返回 暗含总长一致
if(conLen == length) return dfs(dep+1,0,0); //拼好一根后 继续拼另一根
for(int i=pos;i<n;i++){ //从大到小顺序搜索
if(!used[i] && conLen+sticks[i]<= length){
used[i]=1;
if(dfs(dep, conLen+sticks[i], i+1)) return true;
used[i]=0;
if(conLen==0) return false; //剪枝1 第一根
while(i+1<n &&sticks[i+1]==sticks[i]) i++; //剪枝2 相同长度
}
}
return false;//都不满足 返回false
}
int main(){
while(scanf("%d",&n)!=EOF&&n!=0){
int sum=0;
for(int i=0;i<n;i++){
scanf("%d",sticks+i);
sum+=sticks[i];
}
sort(sticks,sticks+n,cmp);
for(int j=sticks[0];j<=sum;j++){
if(sum%j!=0) continue;
memset(used,0,sizeof(used));
length=j;
cntt=sum/j;
if(dfs(0,0,0)) {
printf("%d\n",j);
break;
}
}
}
return 0;
}