/* 有N截木棒,能将它们接成最少数长度相同的木棍,求此时的长度len. */ /* 是经典深搜+剪枝题,需要剪枝 */ #include <iostream> #include <algorithm> #define MAX 64 using namespace std; int len,N,M; //len为原始棍子长度, M为原始棍子数量 int s[ MAX],mark[ MAX]; bool flag; int cmp(int a, int b) { return a > b; } void dfs(int start_stick,int sum,int cnt) { int i; if(cnt==M) { flag=true; } else if(sum==len) { dfs(0,0,cnt+1); } else { for(int pre=-1,i=start_stick;i<N;i++) { if(mark[i]==0 && pre!=s[i] && sum+s[i]<=len) //pre!=s[i] 剪枝1. 相同的数就不用再循环一遍了 { pre=s[i]; mark[i]=1; dfs(i+1,sum+s[i],cnt); mark[i]=0; if(flag||start_stick==0) /* 剪枝2.找到了退出循环。或者,start_stick==0 即第一根木棒都不能找到组合使它们的长度和为len,那么说明当前len不能到达,因为start_stick一定为组合中的一个。 */ return; } } } } int main() { freopen("input.txt","r",stdin); int i,sum; while(scanf("%d",&N)!=EOF && N) { sum = 0; flag=false; for(i=0;i<N;i++) { scanf("%d",&s[i]); sum+=s[i]; } sort(s, s+N, cmp); for(len = s[0];len<sum; len++) { if(sum%len==0) //优化 { M = sum/len; //木棍数肯定为正整数 memset(mark,0,sizeof(mark)); dfs(0,0,0); if(flag==true) { break; } } } printf("%d/n", flag ? len : sum); } return 0; } /* 用这个快速排序 超时了 不知道为什么 int cmp( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(s,N,sizeof(int),cmp); */