1. 程式人生 > >POJ 3134 Power Calculus (叠代剪枝搜索)

POJ 3134 Power Calculus (叠代剪枝搜索)

剪枝搜索 %d 說明 open i++ cal 最大 fin long

題目大意:略

題目裏所有的運算都是冪運算,所以轉化成指數的加減

由於搜索層數不會超過$2*log$層,所以用一個棧存儲哪些數已經被組合出來了,不必暴力枚舉哪些數已經被搜出來了

然後跑$iddfs$就行了

可以加一個剪枝,設你選擇的最大叠代深度為K,現在如果當前組合出的數$x$,滿足$x*2^{K-dep}<n$,說明$n$一定無法被$x$組合出來(即自己不斷加自己),$x$對於答案是一定無意義的,就跳出

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4
#include <algorithm> 5 #define NN 2010 6 #define ll long long 7 #define uint unsigned int 8 #define ull unsigned long long 9 #define inf 0x3f3f3f3f 10 #define idx(X,Y) ((X)*5+(Y)) 11 using namespace std; 12 13 const int maxn=2000; 14 int vis[NN],use[NN],bin[15],a[NN]; 15 int n; 16
int stk[NN],num; 17 int dfs(int dep,int s,int ma) 18 { 19 if(s==n) return 1; 20 if(dep>=ma) return 0; 21 int ans; 22 if(s*(1<<ma-dep)<n) return 0; 23 for(int i=1;i<=num;i++) 24 { 25 int x=stk[i]; 26 if(use[s+x]) continue; 27 use[s+x]=1
,stk[++num]=s+x; 28 ans=dfs(dep+1,s+x,ma); 29 use[s+x]=0,stk[num--]=0; 30 if(ans) return 1; 31 if(s-x<0||use[s-x]) continue; 32 use[s-x]=1,stk[++num]=s-x; 33 ans=dfs(dep+1,s-x,ma); 34 use[s-x]=0,stk[num--]=0; 35 if(ans) return 1; 36 } 37 return 0; 38 } 39 40 int main() 41 { 42 //freopen("t2.in","r",stdin); 43 bin[0]=1; 44 for(int i=1;i<=15;i++) 45 bin[i]=bin[i-1]<<1; 46 for(int s=1;s<=maxn;s++) 47 a[s]=s; 48 while(scanf("%d",&n)&&n!=0) 49 { 50 if(n==1) {printf("0\n");continue;} 51 memset(use,0,sizeof(use)); 52 int ans;use[1]=1; 53 num=0,stk[++num]=1; 54 for(int k=0;k<=20;k++){ 55 ans=dfs(0,1,k); 56 if(ans){ans=k;break;} 57 }printf("%d\n",ans); 58 } 59 return 0; 60 }

POJ 3134 Power Calculus (叠代剪枝搜索)