http://poj.org/problem?id=1011
需要剪枝
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int len,n,sum,s[65],mark[65],num;
int dfs(int i,int req,int left);
int com(int a,int b);
int main(){
scanf("%d",&n);
while(n){
int sum=0;
memset(mark,0,sizeof(mark));
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
sum+=s[i];
}
sort(s,s+n,com);
int flag=0;
for(len=s[0];len<=sum;len++){
if(sum%len==0){
// cout<<len<<endl;
if(dfs(0,len,sum)){
flag=1;
printf("%d\n",len);
break;
}
}
}
if(!flag){
printf("%d\n",sum);
}
scanf("%d",&n);
}
}
int com(int a,int b){
return a>b;
}
int dfs(int i,int req,int left){//i,当前使用的木棍,req当前所需要的长度,left剩下的长度
// cout<<i<<' '<<req<<' '<<left<<' '<<len<<endl;
if(req==0){
int j;
left-=len;
if(left==0) return 1;
for(j=0;mark[j];j++);//剪枝1,找出剩下没有使用的最大的木棍
mark[j]=1;
if(dfs(j,len-s[j],left)) return 1;
mark[j]=0;
left+=len;
}
else{
for(int j=i;j<n;j++){
// cout<<s[j]<<endl;
if(j>0&&(s[j]==s[j-1])&&(!mark[j-1])) continue;//剪枝2,若前面相同长度没有使用,则后面相同长度的木棍也不符合要求
if(mark[j]) continue;//使用未使用过的
if(s[j]>req)continue;//剪枝3,若当前木棍大于需要的,也不符合要求
mark[j]=1;
req-=s[j];
// cout<<s[j]<<endl;
if(dfs(j,req,left)) return 1;
mark[j]=0;
req+=s[j];
}
}
return 0;
}