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\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 }

原文地址:https://www.cnblogs.com/guapisolo/p/10011062.html

时间: 2024-10-07 22:53:29

POJ 3134 Power Calculus (迭代剪枝搜索)的相关文章

poj 3134 Power Calculus iddfs(迭代深搜)

iddfs入门题. //poj 3134 //sep9 #include <iostream> using namespace std; int n,deep; int a[30]; bool iddfs(int pos) { int t; if(pos>deep) return false; if(a[pos]<<(deep-pos)<n) return false; if(a[pos]==n) return true; for(int i=1;i<=pos;+

POJ 3134 - Power Calculus (IDDFS)

题意:求只用乘法和除法最快多少步可以求到x^n 思路:迭代加深搜索 //Accepted 164K 1094MS C++ 840B include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int step[100005]; int n; int cur; bool IDDFS(int lim,int g) { if(cur>

poj 3134 Power Calculus(迭代加深dfs+强剪枝)

Description Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications: x2 = x × x, x3 = x2 × x, x4 = x3 × x, …, x31 = x30 × x. The operation of squaring can be appreciably shorten the sequence of multiplications.

POJ 3134 - Power Calculus

迭代加深 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<queue> #include<vector> using namespace std; int n,num[1000],lim; int dfs(in

【POJ】3134 Power Calculus

1. 题目描述给定一个正整数$n$,求经过多少次乘法或除法运算可以从$x$得到$x^n$?中间结果也是可以复用的. 2. 基本思路实际结果其实非常小,肯定不会超过20.因此,可以采用IDA*算法.注意几个剪枝优化就好了:(1)每次新计算的值必须从未出现过;(2)每次新计算的值进行还可以执行的运算次数的幂运算仍然小于$x^n$,即新值左移还可以执行的次数小于$n$则一定不成立:(3)该值与$n$的绝对值$\Delta$小于$n$,同时还可以执行的次数大于$ans[\Delta]+1$,那么一定成立

UVA - 1374 Power Calculus 迭代深搜

题目大意:问从1变到n至少需要多少步.变换规则如下 1.变化过程中的中间结果可以任意使用 2.每次只能挑选两个数进行加减 解题思路:先算一下至少需要多少步,然后在如果在当前步数下无法到达结果的话,就当前步数加1,继续搜索下去 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 1010 int num[maxn], cnt, n ,MIN_dep

UVA1374 - Power Calculus(迭代深搜+剪枝)

题目链接 题意:给出x和正整数n,问最少需要几次乘除法 可以得到n = x^m 思路:其实是关于指数的操作,即从1到m最少的步数.我们可以先确定最少步数m,然后进行迭代,迭代的过程也就是判断通过相加减所得到的数可以在m次操作中等于n,如果符合,m即为最小步数,如果不符合,m++,进行下一次迭代.迭代过程中要注意剪枝,即剩余的次数如果每次都是取最大值相加还是比n小的话,就直接跳出. 代码: #include <iostream> #include <cstdio> #include

1374 - Power Calculus (迭代加深+剪枝)

题目要求乘除法的最少次数,其实就是一个数组中一开始只有一个数:1 ,每次可以从数组中取两个数(可以取同一个数)相加生成一个新数加如数组 . 那么显然这是一个迭代加深搜索,从小到大枚举深度上限 . 为了降低时间复杂度,我们要尽量的减少迭代次数,所以我们优先做加法,并且优先将最大的两个数相加,这样可以最快的接近目标 . 当然,有一个很显然的剪枝: 当每次取最大的两个数相加仍然小于n时要剪枝 .因为以最快的方式增长的话其指数是按照2的幂次增加的,所以当前最大值maxv*pow(2,maxd-d) <

Power Calculus UVA - 1374 迭代加深搜索

迭代加深搜索经典题目,好久不做迭代加深搜索题目,拿来复习了,我们直接对当前深度进行搜索,注意剪枝,还有数组要适当开大,因为2^maxd可能很大 题目:题目链接 AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <algorithm> 6 #include <cstring> 7 #incl