做了很多剪枝。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 70
int a[N],n,aver,vis[N];
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int dfs(int x,int sum,int pos,int f)
{
if(x==f) return 1;
for(int i=pos;i<=n;i++)
{
int flag=0;
if(sum+a[i]>aver) return 0;///因为元素从小到大排序,如果a[i]太大,后面的就都不符合条件,返回0。
if(!vis[i]&&aver-sum>=a[i])
{
if(!vis[i-1]&&a[i]==a[i-1]) continue;///和前面相等,前面的不行,这个肯定也不行。
vis[i]=1;
if(sum+a[i]==aver) flag=dfs(x+1,0,1,f);
else if(sum+a[i]<aver) flag=dfs(x,sum+a[i],i+1,f);
vis[i]=0;
if(flag) return 1;
if(sum==0) return 0;///如果当前sum为0,那么取的第一个元素一定能够匹配,如果不能,说明剩下的元素没有能和这个元素构成aver的,返回0。
if(sum+a[i]==aver) return 0;
}
}
return 0;
}
int main()
{
while(scanf("%d",&n),n)
{
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
int ans=sum;
qsort(a+1,n,sizeof(a[0]),cmp);
for(int i=n;i>=2;i--)
{
memset(vis,0,sizeof(vis));
if(sum%i==0)
{
aver=sum/i;
if(a[n]>aver) continue;///如果平均值小于最大值,肯定不行。
if(dfs(0,0,1,i))
{
ans=aver;///大木棍数量从大往小搜,搜到的第一个结果一定是最大值。
break;
}
}
}
printf("%d\n",ans);
}
return 0;
}