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

题目大意:略

题目里所有的运算都是幂运算,所以转化成指数的加减

由于搜索层数不会超过$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
");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
",ans);
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/guapisolo/p/10011062.html