hdu1455

/*
分析:
    DFS枝剪经典。


                                  2013-03-03
*/










#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 111

int n,ans;
int aim,ok;
int len[N],flag[N];
int cmp(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
void dfs(int now,int finish,int pre)
{
	if(finish==aim)	{ans=1;return ;}
	if(ans)	return ;
	int i,j;
	for(i=pre+1;i<n;i++)
	{
		if(flag[i])			continue;
		if(now+len[i]>ok)	continue;
		flag[i]=1;
		if(now+len[i]==ok)	dfs(0,finish+1,-1);
		else				dfs(now+len[i],finish,i);
		flag[i]=0;
		if(ans)		return ;
		/*
			这一个很重要,如果以当前这根作为第一根,然后从还某有
		用过的木头中来找出合适的,来和它组成一个完整的,失败了,
		那么就这种组合方法坑定会失败(因为剩下的还没有用过的木头
		中,已经确定这一根无法和其它的组成有效组合),直接return掉
		*/
		if(!now)	return ;
		/*
			长度相同的没有必要进行重复dfs。
		*/
		for(j=i+1;j<n;j++)	if(len[j]!=len[j-1])	break;
		i=j-1;
	}
}
int main()
{
	int i;
	int max,sum;
	while(scanf("%d",&n),n)
	{
		max=sum=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&len[i]);
			sum+=len[i];
			if(len[i]>max)	max=len[i];
		}
		qsort(len,n,sizeof(int),cmp);

		for(i=n;i>=2;i--)
		{
			ans=0;
			if(sum%i)		continue;
			if(sum/i<max)	continue;
			aim=i;ok=sum/i;
			memset(flag,0,sizeof(flag));
			dfs(0,0,-1);
			if(ans)	break;
		}
		printf("%d\n",sum/i);
	}
	return 0;
}


你可能感兴趣的:(hdu1455)