这里有两个重要的剪枝一个是去重复,一个是sum%max1 ,开始用的直接深搜,时间超了,应改用最大的棒长度往后面加,尽量减少运算时间,剪枝。。
你还要我怎样,要怎样,才能减到你满意。。。
#include<stdio.h>
#include <string.h>
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int max1=0,a[70],flag,n,visit[70];
void dfs(int dep, int now_len, int u)
{
if(flag) return;
if(now_len == 0) //目前长度为0,也就是说重新开始
{
int k = 0;
while(visit[k]) k ++;
visit[k] = true;
dfs(dep + 1, a[k], k + 1);
visit[k] = false;
return;
}
if(now_len == max1)
{ // 当前长度为len,即又拼凑成了一根原棒
if(dep == n) flag = true; // 完成的标志:所有的n根小棒都有拼到了
else dfs(dep, 0, 0);
return;
}
for(int i = u; i < n; i ++)
if(!visit[i] && now_len + a[i] <= max1)
{
if(!visit[i-1] && a[i] == a[i-1]) continue; // 不重复搜索:最重要的剪枝
visit[i] = true;
dfs(dep + 1, now_len + a[i], i + 1);
visit[i] = false;
}
}
int main()
{
int i;
while(~scanf("%d",&n)&&n!=0)
{
int sum=0;
flag=0;
max1=0;
memset(visit,0,sizeof(visit));
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
if(max1<a[i])max1=a[i];
}
sort(a,a+n,cmp);
for(;max1<=sum;max1++)
{
if(sum%max1==0)dfs(0,0,0);//剪枝递归
if(flag==1)break;
}
printf("%d\n",max1);
}
return 0;
}