#include <bits/stdc++.h>
using namespace std;
int n,a[70],tot,mx = -1,m;
int x = 0;
bool vis[70];
bool flag = 0;
void dfs(int sum,int count,int last){
if(flag) return;
if(count == tot/x-1){//递归边界,只需要搜索到当前最多的木棒数量(tot/x)再减去1即可。减去1是因为如果其它的都已经知道,那么这个也就可以知道。
flag = 1;
return;
}
for(int i = last+1;i <= n;i++){//last排列变组合,见Line52
if(vis[i]) continue;//如果当前要使用的木棒已经被使用
vis[i] = 1;//标记木棒,使得下次不会被重复使用
if(a[i] + sum == x){//刚好凑出来一根木棒,进入下一根,此时last要归0
dfs(0,count+1,0);
}else if(a[i] + sum < x){//否则继续凑木棒,下一次只需要从 i 开始搜索即可
dfs(a[i]+sum,count,i);
}
//如果 a[i]+sum > x ,则不会进入下一层的递归,不会产生任何的影响
vis[i] = 0;//回溯分支,与上面的成对。见Line61
if(flag == 0 && sum == 0) return;//可行性剪枝1
if(flag == 0 && sum+a[i] == x) return;//可行性剪枝2
}
}
bool cmp(int x,int y){return x>y;}//排序规则,因为必须从大到小排序,否则没有意义
int main(){
cin >> m;//m作为临时变量
for(int i = 1;i <= m;i++){
int k;
cin >> k;
if(k <= 50){//过滤不合法的值
a[++n] = k,mx = max(k,mx);//a[++n]被赋值,mx取最大值
tot += k;//求总和
}
}
sort(a+1,a+1+n,cmp);//排序使得最优
for(int i = mx;i <= tot;i++){//此处是从mx到tot
//不用清零vis数组,上一次遗留的值已经被回溯清零,不会产生影响
if(tot % i == 0){//只有是tot的因数才有可能成为最终的答案
x = i;//给dfs函数存储的i值,如果递归时每一层都存储将会浪费大量的空间
dfs(1,0,0);//开始递归,初始选择第1根木棒填充,已经填充0个单位长度,从第0个开始
if(flag == 1){//出现正解,为最小的答案
cout << i;//输出
return 0;//程序结束
}
flag = 0;//否则要将这里归0
}
}
return 0;//不可能用到的结束条件
}