http://poj.org/problem?id=1011
这是一道POJ的搜索的题目,最开始确实难以理解,但做过一些搜索的题目后,也没那么难了。
大概题意就是,现在有N根木头,要拼成若干根木头,并且这些木头要相等的长度,并且每一根木头都要用上,求组成的木头最短长度是多少
思路:
首先木头肯定要由大到小进行排序,组成的最短的木头的长度的范围应该在最长的木头到所有的木头之和之间。
其次就是木头使用过后不能在使用,所以木头应该进行标记。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int num,n,sum,a[500],alen; 6 bool mark[500]; 7 8 int cmp(const void *a,const void *b) 9 { 10 return *((int *)b)-*((int *)a); 11 } 12 13 int dfs(int stick,int len,int pos) //stick代表组成的第几根棍子,len表示当前组成的棍子的长度,pos表示现在的用的几根木棍。 14 { 15 if(stick==num) return 1; //如果组成的木棍数等于预计的木棍数,则搜索成功。 16 for(int i=pos;i<n;i++) 17 { 18 if(!mark[i]) continue; //如果这一根木棍用过,则跳过这个木棍。 19 if(a[i]+len==alen){ 20 mark[i]=false; 21 if(dfs(stick+1,0,0)) //如果第i根木棍成功匹配,则进行下一个木棍的匹配。 22 return 1; 23 mark[i]=true; //如果下一个木棍未匹配成功的话,则当前这个木棍是不能使用的。 24 return 0; 25 }else if(a[i]+len<alen){ 26 mark[i]=false; 27 if(dfs(stick,len+a[i],i)) //当前木棍加起来比预计的长度要短,则搜索下一个木头,看是否可以匹配到。 28 return 1; 29 mark[i]=true; //如不能寻找到,则这个木头也是不能使用的。 30 if(len==0) break; 31 while(a[i]==a[i+1]) i++; //如果当前的a[i]不能用,且a[i]==a[i+1]的话,那么a[i+1]也没用,如果程序可以运行到这来,则说明a[i]是不能与当前这根木头所匹配的。 32 } 33 } 34 return 0; 35 } 36 37 int main() 38 { 39 40 while(scanf("%d",&n),n!=0) 41 { 42 sum=0; 43 for(int i=0;i<n;i++){ 44 scanf("%d",&a[i]); 45 sum+=a[i]; 46 } 47 qsort(a,n,sizeof(a[0]),cmp); 48 for(alen=a[0];alen<=sum;alen++) //最坏的情况也就是只有一根木头,所以alen是小于sum的,我也就这里错了,wa了几次 49 if(sum%alen==0) { 50 memset(mark,true,sizeof(mark)); 51 num=sum/alen; 52 if(dfs(1,0,0)){ 53 printf("%d ",alen); 54 break; 55 } 56 } 57 } 58 return 0; 59 }