Poj 1011
传说中的经典深搜
开始一直没有思路,后来是看了http://www.cnblogs.com/mycapple/archive/2012/08/14/2638430.html,基本是仿照了他的思路一……
剪枝1 木棍长度越长约束越大,将木棍从大到小排序
剪枝2 当前木棍长度大于拼成当前搜索长度所需的剩余长度时剪枝
剪枝3 若当前长度的木棍不符合要求,则与他同长度的木棍也不能符合要求,跳过
剪枝4 当前剩余木棍中的最长木棍无法拼成当前搜索长度,则当前搜索长度不符合要求,返回0
深搜这方面自己真的太弱了。
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 int number; 6 int sticks[64]; 7 int used[64]={0}; 8 int sum; 9 int maxx; 10 int minn; 11 int now_len; 12 int length; 13 14 bool dps(int k,int cleft,int left){ 15 if(left==0){ 16 return true; 17 } 18 if(k==number){ 19 return 0; 20 } 21 for(int i=k;i<number;i++){ 22 if(!used[i]&&sticks[i]<=cleft){ 23 used[i]=1; 24 if(sticks[i]==cleft&&dps(0,now_len,left-sticks[i])){ 25 return 1; 26 } 27 if(dps(i+1,cleft-sticks[i],left-sticks[i])){ 28 return 1; 29 } 30 used[i]=0; 33 if(cleft==now_len) return 0; 34 while(true){ 35 if(sticks[i+1]==sticks[i]){ 36 i++; 37 } 38 else{ 39 break; 40 } 41 } 42 } 43 } 44 return 0; 45 } 46 47 void cmp(int &a,int &b){ 48 int temp; 49 if(a<b){ 50 temp=a; 51 a=b; 52 b=temp; 53 } 54 } 55 56 int main(){ 57 while(cin>>number){ 58 if(number==0){ 59 break; 60 } 61 sum=0; 62 for(int i=0;i<number;i++){ 63 cin>>sticks[i]; 64 sum+=sticks[i]; 65 } 66 for(int i=0;i<number-1;i++){ 67 for(int j=i+1;j<number;j++){ 68 cmp(sticks[i],sticks[j]); 69 } 70 } 71 memset(used,0,sizeof(used)); 72 maxx=sticks[0]; 73 minn=sticks[number-1]; 74 now_len=maxx; 75 length=sum; 76 for(;now_len<sum;now_len++){ 77 if(sum%now_len==0&&dps(0,now_len,sum)){ 78 length=now_len; 79 break; 80 } 81 } 82 cout<<length<<endl; 83 } 84 }