//纯暴力写法:
//本题要求我们根据题目给出的各个小棍的长度,组成若干个长度相同的大棍
//我们可以先枚举大棍的长度len(最长的小棍长度至所有小棍长度之和),并求其对应的大棍个数num
//根据每一轮的len和num,我们以每一根大棍可以由哪些小棍来组成为搜索顺序去dfs深搜,
//从而将num个长度均为len大棍所有可能的小棍组成都遍历到
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int q[65];
int n, sum, len, num;
bool st[65];
bool dfs(int cnt, int l)
{
if(cnt == num) return true;
if(l == len) return dfs(cnt + 1, 0);
for(int i = 0; i < n; i ++)
{
if(st[i] == 0 && l + q[i] <= len)
{
st[i] = 1;
if(dfs(cnt, l + q[i])) return true;
st[i] = 0;
}
}
return false;
}
int main()
{
while(cin >> n && n != 0)
{
cin >> n;
memset(st, 0, sizeof st);
int maxs = -1;
sum = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d",&q[i]);
maxs = max(maxs, q[i]);
sum += q[i];
}
for(len = maxs; len <= sum; len ++)//枚举所有大棍可能的长度
{
if(sum % len == 0)
{
num = sum / len;
if(dfs(0, 0)) break;
}
}
cout << len << endl;
}
return 0;
}
----------------------------------------------------
//本题要求我们根据题目给出的各个小棍的长度,组成若干个长度相同的大棍,并求出大棍最小可能的长度
//我们可以先枚举大棍的长度len(最长的小棍长度至所有小棍长度之和),并求其对应的大棍个数num
//根据每一轮的len和num,我们以每一根大棍可以由哪些小棍来组成为搜索顺序去dfs深搜,
//从而将num个长度均为len大棍所有可能的小棍组成都遍历到
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int q[65];
int n, sum, len, num;
bool st[65];
bool dfs(int cnt, int l, int start)
{
if(cnt == num) return true;
if(l == len) return dfs(cnt + 1, 0, 0);
//排除等效冗余1:按照组合型方式去枚举大棍的小棍组成(因为在大棍中,小棍的排列顺序无所谓)
for(int i = start; i < n; i ++)
{
if(st[i] == 0 && l + q[i] <= len)//可行性剪枝2:大棍的长度不得超过上限len,否则不合法
{
st[i] = 1;
if(dfs(cnt, l + q[i], i + 1)) return true;
//else while(q[i] == q[i + 1] && i + 1 < n) i ++;
st[i] = 0;
//?????可以解释一下排除冗余2、3操作
//排除等效冗余2:如果接入失败的小棍接入的位置是大棍的第一个放置小棍的位置,那么后续操作也一定会失败
//排除等效冗余3:如果接入失败的小棍接入的位置是大棍的最后一个放置小棍的位置,那么后续操作也一定会失败
if(l == 0) return false;
if(l + q[i] == len) return false;//?????为什么是等于而不是大于
//排除等效冗余4:当该小棍无法接入大棍时,则与该小棍长度一致的其余编号的小棍也无法接入,
//从而可以直接跳过枚举,这步操作要放在排除等效冗余2、3之后进行,否则会TLE,因为2、3操作
//可以直接返回到上一层
int j = i;
while (j < n && q[j] == q[i]) j ++ ;
i = j - 1;
}
}
return false;
}
int main()
{
while(cin >> n && n != 0)
{
memset(st, 0, sizeof st);
int maxs = -1;
sum = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d",&q[i]);
maxs = max(maxs, q[i]);
sum += q[i];
}
//优化搜索顺序:让大一些的小棍先进行拼接,从而使得下一层分支较少
sort(q, q + n, greater<int>());
for(len = maxs; len <= sum; len ++)//枚举所有大棍可能的长度
{
//可行性剪枝1:大棍的长度必须能整除总长度
if(sum % len == 0)
{
num = sum / len;
if(dfs(0, 0, 0)) break;
}
}
cout << len << endl;
}
return 0;
}