#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=1e7;
int n,l,sum;
int a[maxn];
int v[maxn];
int cmp(int a,int b)
{
return a>b;
}
int dfs(int len,int num,int pos)
{
if(l*num==sum) return 1;
for(int i=pos; i<n; i++)
{
if(v[i]||(i&&!v[i-1]&&a[i-1]==a[i])) continue;
if(len+a[i]==l)
{
v[i]=true;
if(dfs(0,num+1,0)) return 1;
v[i]=false;
return 0;
}
else if(len+a[i]<l)
{
v[i]=true;
if(dfs(len+a[i],num,i+1)) return 1;
v[i]=false;
if(!len) return 0;
}
}
return 0;
}
void solve()
{
int flag=0;
for(l=a[0]; l<=sum/2; l++)
{
if(sum%l) continue;
memset(v,0,sizeof(v));
if(dfs(0,0,0))
{
flag=1;
break;
}
}
if(flag)
printf("%d\n",l);
else printf("%d\n",sum);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif
while(scanf("%d",&n)==1&&n)
{
sum=0;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a,a+n,cmp);
solve();
}
return 0;
}
题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=243
题解:
1.将木棒从大到小排序,优先使用大的木棒,加快组合速度。
2.木棒长度介于max到sum/2之间。
3.原木棒长度为sum约数。
4.对于第i根木棒,若a[i]==a[i-1]且第i-1根木棒未被选上,则第i根同样不会被选上。
5.若当前在拼接第i根木棒的第一段,若使用剩余可使用最长木棒拼接失败,则退出搜索(当元素多时不符合要求,元素减少时一定不符合)。