hdu 1455 poj 1011 sticks
dfs+剪枝,一道很好的题目,只是我不会写,求教了别人才写对了,发现以前写过的。。我勒个去,但以前那条过不去的。。。安慰。。
剪枝部分有很多。。最大就是搜索的时候如果发现k这个木条可以用的时候,递归下一次搜索的时候就应该从k+1开始搜索而不是0开始从新搜索,否则他会重复的搜索k前面一些之前搜索失败的木棍,这样就浪费了很多时间了。。
还有就是要先排序再搜索,先搜索大木条,因为他的限制的比较好,搜索出来的情况会容易控制点。。。
View Code
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> #define min(a,b) a<b?a:b int s[70],n; int v[70],asum; int cmp(const void*x,const void*y) { return *(int *)y-*(int *)x; } int dfs(int len,int pre,int sum,int ll) { int i; if(pre==len) { if(sum+1==asum/len) return 1; for(i=0;i<n;i++) if(!v[i]) { v[i]=1; if(dfs(len,s[i],sum+1,i+1)) return 1; { v[i]=0; while(s[i]==s[i+1]) i++; } break; } } for(i=ll;i<n;i++) if(!v[i]&&pre+s[i]<=len&&s[i]) { v[i]=1; if(dfs(len,pre+s[i],sum,i+1)) return 1; else { v[i]=0; while(s[i]==s[i+1]) i++; } } return 0; } int main() { int i,ans; while(scanf("%d",&n),n!=0) { int min=100000; asum=0; for(i=0;i<n;i++) { scanf("%d",&s[i]); asum+=s[i]; if(s[i]<min) min=s[i]; } qsort(s,n,sizeof(int),cmp); memset(v,0,sizeof(v)); for(i=n;i>=1;i--) if(asum%i==0&&asum/i>=min&&s[0]<=asum/i&&dfs(asum/i,0,0,0)) { ans=asum/i; printf("%d\n",ans); break; } } return 0; }