POJ3134 Power Calculus IDA*搜索的一个应用

题目链接:http://poj.org/problem?id=3134

题目给出一个初始的x,要求操作只能是乘与除,问最少需要多少步才能算出x^n。这道题等价于给一个1,只能加或者减,问最少需要多少步才能得到n。可以把n拆开成许多个数相加或者相减,从搜索的角度来讲,用普通dfs的话很可能深度达到1000,所以可以对depth进行遍历,并且设置估价函数进行剪枝,只要当前的值以最快的方式迭代也不能得到n则说明在当前设置的深度下是不能达到预期的结果的。

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define abs(x) (x)>0?(x):(-(x))
 4 using namespace std;
 5 int n;
 6 int a[1005];
 7 int tmp=0;
 8 bool dfs(int cur,int dep)//当前搜索深度,目标深度
 9 {
10     if((a[cur-1]<<(dep-cur))<n)return false;//以最快的方式迭代也不能得到最终的结果
11     if(cur>dep)return false;
12     if(cur==dep&&a[cur-1]==n)return true;
13     for(int i=0;i<cur;i++)//对前面已经获得的加数进行枚举
14     {
15         a[cur]=a[cur-1]+a[i];//a[cur-1]是前面已经得到的最终加数
16         if(dfs(cur+1,dep))return true;
17         a[cur]=abs(a[cur-1]-a[i]);
18         if(dfs(cur+1,dep))return true;
19     }
20     return false;
21 }
22 int main()
23 {
24     while(scanf("%d",&n)&&n)
25     {
26         int dep=0;//目标深度代表操作次数
27         tmp=0;
28         while(1)
29         {
30             a[0]=1;
31             if(dfs(1,dep))break;
32             dep++;
33         }
34         printf("%d\n",dep-1);//由于在第0层没有操作,所以减一
35     }
36  } 

原文地址:https://www.cnblogs.com/randy-lo/p/12610565.html

时间: 2024-08-27 04:40:20

POJ3134 Power Calculus IDA*搜索的一个应用的相关文章

UVa1374 Power Calculus (IDA*)

链接:http://acm.hust.edu.cn/vjudge/problem/41552分析:枚举最大深度maxd,每次总是使用“刚刚得到”的那个数(LRJ说的我信了),每次递归枚举a[d+1],两种方式a[d]+或-去a[i],找到解返回true,否则直至枚举结束都没有找到解则返回false,dfs出口有四个,一是a[d]==n,说明最少用d次操作能得到目标,二是枚举完所有a[d+1]也没找到解,然后加上两个剪枝,深度大于等于最大深度还有乐观估计接下来maxd-d次每次都取指数最大相加但结

Power Calculus 快速幂计算 (IDA*/打表)

原题:1374 - Power Calculus 题意: 求最少用几次乘法或除法,可以从x得到x^n.(每次只能从已经得到的数字里选择两个进行操作) 举例: x^31可以通过最少6次操作得到(5次乘,1次除) x^2 = x*x x^4 = (x^2)*(x^2) x^8 = (x^4)*(x^4) x^16 = (x^8)*(x^8) x^32 = (x^16)*(x^16) x^31 = (x^32)÷x 分析: 可以看到,每次从已得到的数字中选取两个操作,这样就有了枚举的思路. 这道题又是

[2016-03-03][UVA][1374][Power Calculus]

[2016-03-03][UVA][1374][Power Calculus] 时间:2016-03-03 16:14:01 星期四 题目编号:UVA 1374 题目大意:给出x的指数n,问,x经过多少次相乘才能得到x^n 输入:n 输出:次数 分析: 求乘法的所有可能方式,用dfs,适当剪枝优化,变成IDA* x的乘法,变成了指数的加法 每次不断平方,最少次数 为 不断平方的次数.这个为maxd起点 方法: 枚举每一位出现过的次数,当前字数加上枚举出来的次数,进入下一层dfs 剪枝:如果预计最

[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]

题目链接 : BZOJ 1085 题目分析 : 本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧. 我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS 验证在当前枚举的步数之内能否到达目标状态. 如果不能到达,就枚举下一个步数,重新搜索,即使某些状态在之前的 DFS 中已经搜索过,我们仍然搜索. 并且在一次 DFS 中,我们不需要判定重复的状态. 在 IDA* 中,重要的剪枝优化是 估价函数 ,将一些不可能存在可行解的枝条剪掉. 如果估价函数写得

HDU 3220 IDA*搜索 || BFS

给出一个16个点所构成的图形,分别由0,1组成,每次操作可以任选其中相连的两个点(必须一个为0,一个为1),进行0,1,交换 问3步内是否可以把图形变成:0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1状态 若不行,输出more 状压存储图形状态.ida*搜索  或者 BFS都行 IDA*搜索 #include "stdio.h" #include "string.h" const int b[]={0,1,2,4,8,16,32,64,128,256

[BZOJ 1085][SCOI 2005]骑士精神(IDA*搜索)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085 考虑到深度不超过15,IDA*搜索可做. 估价函数h()=当前不在目标位置的棋子个数. 然后其他细节就和普通的迭代加深一样了. #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm>

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

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

[ jquery 过滤器 siblings(expr) ] 此方法用于在选择器的基础之上搜索取得一个包含匹配的元素集合中每一个元素的所有唯一同辈元素的元素集合,可以用可选的表达式进行筛选

此方法用于在选择器的基础之上搜索取得一个包含匹配的元素集合中每一个元素的所有唯一同辈元素的元素集合,可以用可选的表达式进行筛选 实例: <html lang='zh-cn'> <head> <title>Insert you title</title> <meta http-equiv='description' content='this is my page'> <meta http-equiv='keywords' content='

IDA 搜索中文字符串

IDA 搜索中文字符串 IDA 的字符串窗口默认只能显示英文,网上的一些方法是指定启动时的参数可以显示中文 ida64 -DCULTURE=all ida -DCULTURE=all 还有就是修改 cfg/ida.cfg 文件,但是这两种方法都没试成功.实际上没有那么麻烦,IDA 7.0 操作很方便,在字符串列表窗口右键点击 Setup,如下图所示. 对话框勾上 Unicode C-style (16 bits),点击 OK,如下图所示.另外需要注意的是图中最后面的 Minimal string