迭代加深搜索 codevs 2541 幂运算

codevs 2541 幂运算

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

从m开始,我们只需要6次运算就可以计算出m31:

m2=m×m,m4=m2×m2,m8=m4×m4,m16=m8×m8,m32=m16×m16,m31=m32÷m。

请你找出从m开始,计算mn的最少运算次数。在运算的每一步,都应该是m的正整数次方,换句话说,类似m-3是不允许出现的。

输入描述 Input Description

输入为一个正整数n

输出描述 Output Description

输出为一个整数,为从m开始,计算mn的最少运算次数。

样例输入 Sample Input

样例1
1

样例2
31

样例3
70

样例输出 Sample Output

样例1
0

样例2
6

样例3
8

数据范围及提示 Data Size & Hint

n(1<=n<=1000)

数据没有问题,已经出现过的n次方可以直接调用

 1 /*迭代加深搜索的含义:就是dfs前,先规定好dfs的深度,如果到了这个深度还没有结果,就退出dfs,没找到,在这个题目中深度就指的是计算的次数,实现规定好计算的次数,在这个次数内没有出现结果,就返回没找到,对于那种没有搜索边界的题目,可以这样做*/
 2 /*因为这个题目没有说最多对计算多少次,那么如果对于一个结果一直dfs计算下去,不仅没有边界,而且计算的次数也不一定是最少次数。所以用迭代加深搜索。
 3 */
 4 #include<iostream>
 5 using namespace std;
 6 #include<cstdio>
 7 #define MAXdeep 20/*规定最多计算次数*/
 8 int a[MAXdeep];
 9 bool dfs(int k,int maxdepth,int n)
10 {
11     if(a[k]==n)
12       return true;
13     if(k==maxdepth) return false;
14     int maxx=a[0];
15     for(int i=1;i<=k;++i)
16       maxx=max(maxx,a[i]);/*一个非常合理的剪枝,如果每次把指数*2,这是最大的增长方式,如果这样还是比n小,就退出吧*/
17     if((maxx<<(maxdepth-k))<n) return false;
18     for(int i=k;i>=0;--i)
19     {/*这里采用倒序循环可以加快速度,先选出比较大的数计算,可以加快扩展速度*/
20         a[k+1]=a[i]+a[k];
21         if(dfs(k+1,maxdepth,n)) return true;
22         a[k+1]=a[k]-a[i];
23         if(dfs(k+1,maxdepth,n)) return true;
24     }
25     return false;
26 }
27 int solve(int n)
28 {
29     if(n==1) return 0;
30     a[0]=1;
31     for(int i=1;i<MAXdeep;++i)
32       if(dfs(0,i,n)) return i;/*依次加深深度*/
33     return MAXdeep;
34 }
35 int main()
36 {
37     int n;
38     scanf("%d",&n);
39     printf("%d\n",solve(n));
40     return 0;
41 }
时间: 2024-12-27 08:07:47

迭代加深搜索 codevs 2541 幂运算的相关文章

codevs 2541 幂运算(迭代加深搜索)

2541 幂运算 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出m31: m2=m×m,m4=m2×m2,m8=m4×m4,m16=m8×m8,m32=m16×m16,m31=m32÷m. 请你找出从m开始,计算mn的最少运算次数.在运算的每一步,都应该是m的正整数次方,换句话说,类似m-3是不允许出现的. 输入描述 Input Description 输入为一个正整数n 输出描述

codevs 2541 幂运算(迭代加深搜索)

/* 一开始想到了简单的深搜 维护当前可用的mi数组 然后回溯用哪个 不断更新新产生的mi 这样的问题是 由于mi不断产生 搜索规模扩大 不好 不好 下面是奇丑的WA掉的代码 做个反面教材 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,ans=0x3f3f3f3f,f[1055],s[1055],top,vis[1055]; void Dfs(int

UVa 1374 - Power Calculus——[迭代加深搜索、快速幂]

解题思路: 这是一道以快速幂计算为原理的题,实际上也属于求最短路径的题目类型.那么我们可以以当前求出的幂的集合为状态,采用IDA*方法即可求解.问题的关键在于如何剪枝效率更高.笔者采用的剪枝方法是: 1)如果当前状态幂集合中的最大元素max满足 max*2^(maxd-cur_d)<n,则剪枝.原因是:在每一次状态转移后,max最多增大一倍.(maxd-cur_d)次转移之后,max最多变成原来的2^(maxd-cur_d)倍,然而如果当前状态的极限情况下仍有max<n,则当前状态结点一定无法

Codevs 四子连棋 (迭代加深搜索)

题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Input Description 从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用

2541 幂运算

2541 幂运算 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 从m开始,我们只需要6次运算就可以计算出m31: m2=m×m,m4=m2×m2,m8=m4×m4,m16=m8×m8,m32=m16×m16,m31=m32÷m. 请你找出从m开始,计算mn的最少运算次数.在运算的每一步,都应该是m的正整数次方,换句话说,类似m-3是不允许出现的. 输入描述 Input Description 输入为一

埃及分数问题_迭代加深搜索_C++

一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19/45=1/3 + 1/12 + 1/180 二.迭代加深搜索 迭代加深搜索可以看做带深度限制的DFS. 首先设置一个搜索深度,然后进行DFS,当目前深度达到限制深度后验证当前方案的合理性,更新答案. 不断调整搜索深度,直到找到最优解. 三.埃及分数具体实现 我们用dep限制搜索层数,先从2开始,每

迭代加深搜索[codevs1004 四子连棋]

迭代加深搜索 一.算法简介 迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式.由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案. 迭代加深搜索适用于当搜索深度没有明确上限的情况. 例如上图的一棵搜索树,在进行深度优先搜索前先规定好这次搜索的最大深度dep,当搜索到达dep却还没搜索到结果时回溯. 之后不断加大搜索深度,重新搜索,直到找到结果为止.虽然这样搜索次数会累计很多次,但每一次搜索的范围和下一次搜索的范围相比微不足道,所以整体搜索速度不会受

UVA-11214 Guarding the Chessboard (迭代加深搜索)

题目大意:在一个国际象棋盘上放置皇后,使得目标全部被占领,求最少的皇后个数. 题目分析:迭代加深搜索,否则超时. 小技巧:用vis[0][r].vis[1][c].vis[2][r+c].vis[c-r+N]分别标志(r,c)位置相对应的行.列.主.副对角线有没有被占领(详见<入门经典(第2版)>P193),其中N表示任意一个比行数和列数都大(大于等于)的数. 代码如下: # include<iostream> # include<cstdio> # include&l

USACO/fence8 迭代加深搜索+剪枝

题目链接 迭代加深搜索思想. 枚举答案K,考虑到能否切出K个木头,那么我们当然选最小的K个来切. 1.对于原材料,我们是首选最大的还是最小的?显然,首选大的能够更容易切出,也更容易得到答案. 2.对于目标木头,我们是优先得到最大的还是最小的?显然,由于K个木头我们都要得到,那么当然先把最大的(最难得到的)先得到,这种搜索策略更优. 3.假设总原材料为all,前K个木头总和为sum,那么all-sum就是这一次切割过程中能[浪费]的最大数目.对于一个切剩下的原材料,若它比最小的目标木头还要小,则它