传送门: http://poj.org/problem?id=1011
题目大意:
给出一些棍棒的长度,求把他们拼接成长度一样的若干棍棒的最小长度(全部用完),
经典的DFS+ 剪枝
和别人的代码一样的剪枝为啥我的172MS人家32MS甚至16 为啥。。。。。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define F(i,R) for(int i=0;i<R;i++)
int a[64+2];
bool used[64+2];
int n;
bool cmp(const int &a,const int &b)
{
return a>b;
}
bool dfs(int cur,int sum,int target) //已经拼成的个数 现在拼的长度 目标长度
{
if(cur==n && sum==target)
return true;
if(sum==target)
sum=0;
for(int i=0;i<n;i++)
{
if(used[i]==true)
continue;
if(sum+a[i] > target) //剪枝2,如果当前拼接的大于目标那么没必要继续了
continue;
used[i]=true;
if(dfs(cur+1,sum+a[i],target))
return true;
used[i]=false;
if(sum==0) //最重要的剪枝!如果找不到和当前匹配的那么直接跳出循环。
break;
while(a[i] == a[i+1])//剪枝3,如果当前的棍子不满足那么和它相等的也不行
i++;
}
return false;
}
int main()
{
while(scanf("%d",&n),n)
{
int sum=0;
F(i,n)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a,a+n,cmp);
int i;
for(i=a[n-1];i<=sum;i++)
{
if(sum % i !=0) continue; //剪枝1
memset(used,0,sizeof(used));
if(dfs(0,0,i))
break;
}
printf("%d\n",i);
}
}