http://acm.hdu.edu.cn/showproblem.php?pid=1455
Test instructions: A few lengths of sticks are divided into a lot of halves. Ask to synthesize multiple sticks of the same length, the length of the stick is the smallest.
The puzzle: It's obviously Dfs. So we first need to find out, these sticks can be how long, is certainly the length of the longest stick to a certain length between all stick lengths and. After finding these possibilities, start searching directly at this length. The idea is to search and record for this length, and then re-search, until all the sticks have been assigned since the completion.
Important pruning: Determine the starting position of each search, this must be OK!!! Next is the same length of the stick, one does not meet the other certainly does not meet! So use the pre to record the non-conforming stick length in front!
#include <stdio.h>#include<string.h>#include<algorithm>using namespacestd;inta[ $],vis[ $],n,flag,ans,sum,ss;intGreedy (intMaxintsum);voidDfsintMaxintPosintValueintdepth);BOOLCompareintAintb) { returnA>b;}intMain () {Freopen ("a.txt","R", stdin); while(SCANF ("%d", &n)!=eof&&n!=0) {flag=ans=sum=ss=0; Memset (A,0,sizeof(a)); memset (Vis,0,sizeof(VIS)); intmax=0; for(intI=0; i<n;i++) {scanf ("%d",&A[i]); if(Max<a[i]) max=A[i]; Sum+=A[i]; } sort (A,a+n,compare);//from large to small sort in order to facilitate the search, because it is obvious that the longer the stick his variability is smaller, so first look for long. printf ("%d\n", greedy (max,sum)); }return 0;} Find out how many kinds of stick lengths are possibleintGreedy (intMaxintsum) { intk=0, res[ +]; for(inti=max;i<sum;i++){ if(sum%i==0) {Res[k]=i; K++; } } for(intI=0; i<k;i++) {memset (Vis,0,sizeof(VIS)); SS=0; DFS (res[i),0,0,0); if(ss==1)returnRes[i]; } returnsum;}voidDfsintMaxintPosintValueintdepth) { if(ss==1){ return; } if(value==max) {Depth++; if(depth==sum/max) {SS=1; return; } DFS (max,0,0, depth); return; } if(pos==n) {//over the length of the stick, stating no possibility, so directly to return return; } intpre=-1;//here the pre is used to record whether the currently found stick matches, does not conform to the words, it is recorded, in the selection of other times not the same as him. for(inti=pos;i<n;i++){ if(!vis[i]&&a[i]+value<=max&&a[i]!=pre) { //first of all to ensure that it has not been visited, and then to determine whether the current length plus this is less than the target length, and the other is to ask the stick and the front of the different. Pre=A[i]; Vis[i]=1; DFS (Max,i+1, value+a[i],depth); Vis[i]=0; if(pos==0){return;} //artifact of the pruning, his artifact is that the first time the search of the stick when the situation is sure to match!! Determine the starting location for each search!! } }}
HDU 1455 Sticks--dfs Classic Topics