1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 using namespace std;
6 bool anUsed[65];
7 int L,N,stick[65];
8 bool cmp(int a,int b)
9 {
10 return a>b;
11 }
12 bool DFS(int nUnusedSticks,int nLeft)
13 {
14 int i,j,k;
15 if(!(nUnusedSticks||nLeft)) return 1;//假如都为0,则拼合完成
16 if(!nLeft) nLeft=L;//新建一个要拼合的棍
17 for(i=0;i<N;++i)
18 if(!anUsed[i]&&stick[i]<=nLeft){//剪枝
19 if(i>0&&!anUsed[i-1]&&stick[i]==stick[i-1]) continue;//剪枝
20 anUsed[i]=1;
21 if(DFS(nUnusedSticks-1,nLeft-stick[i])) return 1;
22 anUsed[i]=0;//可以重新再使用
23 if(stick[i]==nLeft||nLeft==L) return 0;//下一次的递归深入中,刚建了一个新棍,结果后面没有符合条件的棍,返回这一层时stick[i]==nLeft,而这一层也要返回
24 } //或者这一层刚开了一个新的棍,但剩余棍中没有符合的棍即nLeft==L,这也需要返回上层
25 return 0;
26 }
27 int main()
28 {
29 int i,totalLength;
30 while(scanf("%d",&N),N){
31 for(totalLength=i=0;i<N;++i){
32 scanf("%d",&stick[i]);
33 totalLength+=stick[i];
34 }
35 sort(stick,stick+N,cmp);//一次剪枝
36 for(L=stick[0];L<=(totalLength>>1);++L)
37 if(totalLength%L==0){ //二次剪枝
38 memset(anUsed,0,sizeof(anUsed));
39 if(DFS(N,L)) break;
40 }
41 if(L>(totalLength>>1)) printf("%d\n",totalLength);//三次剪纸
42 else printf("%d\n",L);
43 }
44 return 0;
45 }