题目链接:http://poj.org/problem?id=1011
这类递归的题目真是太伤脑筋了,对我这个新手来说非常勉强,参考了很多代码才堪堪AC,剪枝即设置递归条件,防止程序进行过多的递归导致超时,我觉得重点还是递归,照我的理解条件有以下几条:
1、可能的长度一定大于等于棍子里最长的棍子;
2、可能的长度是所有根子长度总和的因子,即总长度%可能长度==0;
3、若某一根棍子无法产生一种组合使得其等于可能长度,则此可能长度无效;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
int a[66];
int visit[66];
int n=0;
void sort(int a[],int n)
{
int i;
int j;
int t;
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
if(a[i]<a[j]){
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
}
int dfs(int count,int temp,int ans,int s)
{
int j=0;
if(count==0&&temp==0)
return 1;
if(temp==0) {
temp=ans;
}
int sample=-1;
for(j=s;j<n;j++) {
if(visit[j]==1||a[j]==sample)
continue;
if(a[j]>temp)
continue;
visit[j]=1;
if(temp-a[j]==0){
if(dfs(count-1,temp-a[j],ans,0))
return 1;
}
else{
if(dfs(count-1,temp-a[j],ans,j))
return 1;
}
visit[j]=0;
sample=a[j];
if(temp==ans||temp==a[j])
break;
}
return 0;
}
int main()
{
int i;
int max;
int len;
int sum;
int flag;
//freopen("d:\\in.txt","r",stdin);
while(scanf("%d",&n),n!=0){
for(i=0,max=0,sum=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
visit[i]=0;
}
sort(a,n);
max=a[0];
for(flag=0;max<=sum/2;max++){
if(sum%max!=0){
continue;
}
len=sum/max;
if(dfs(n,0,max,0)==1){
flag=1;
printf("%d\n",max);
break;
}
}
if(flag==0){
printf("%d\n",sum);
}
}
return 0;
}