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

题目链接

题意:给出x和正整数n,问最少需要几次乘除法 可以得到n = x^m

思路:其实是关于指数的操作,即从1到m最少的步数。我们可以先确定最少步数m,然后进行迭代,迭代的过程也就是判断通过相加减所得到的数可以在m次操作中等于n,如果符合,m即为最小步数,如果不符合,m++,进行下一次迭代。迭代过程中要注意剪枝,即剩余的次数如果每次都是取最大值相加还是比n小的话,就直接跳出。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

const int MAXN = 1005;
using namespace std;

int arr[MAXN];
int n, depth, num;

void init() {
    depth = 0;
    int temp = 1;
    while (n > temp) {
        temp = temp * 2;
        depth++;
    }
}

int dfs(int cur, int d) {
    if (d >= depth) {
        if (cur == n)
            return true;
        return false;
    }
    for (int i = num - 1; i >= 0; i--) {
        int Max = 0;
        for (int j = 0; j < num; j++)
            Max = max(Max, arr[j]);
        if ((cur + Max) << (depth - d - 1) < n)
            return false;
        arr[num++] = cur + arr[i];
        if (dfs(cur + arr[i], d + 1))
            return true;
        num--;
        arr[num++] = cur - arr[i];
        if (dfs(cur - arr[i], d + 1))
            return true;
        num--;
    }
    return false;
}

int main() {
    while (scanf("%d", &n) && n) {
        if (n == 1) {
            printf("0\n");
            continue;
        }
        init();
        while (1) {
            memset(arr, 0, sizeof(arr));
            arr[0] = num = 1;
            if (dfs(1, 0))
                break;
            depth++;
        }
        printf("%d\n", depth);
    }
    return 0;
}

UVA1374 - Power Calculus(迭代深搜+剪枝),布布扣,bubuko.com

时间: 2024-10-06 09:27:15

UVA1374 - Power Calculus(迭代深搜+剪枝)的相关文章

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

bzoj 1085骑士精神 迭代深搜

题目传送门 题目大意:给出一幅棋盘,问能否复原,中文题面,不做解释. 思路:第一次写迭代深搜的题目,这道题还是挺经典的.这道题的状态很明显的每多搜一层就是多八倍,非常的多,而且又是t组输入,所以必定有很多点是在深层次的,所以用迭代深搜,这就是很多组数据在很浅的层就得到了答案,不需要多做了,而有一些样例则是确实会重复计算(答案层次比较深的时候),但是此时浪费的时间和之前节约的时间已经不是一个数量级的了,故用迭代深搜,这也是迭代深搜的标志性功能. 但是光迭代深搜没有用,还需要一个估价函数来剪枝,这里

poj1011(深搜+剪枝)

题意:给m根木棍,将它们重新拼成n根一样长的木棍,并使得n尽量大(即每个新木棍尽量短). 解法:经典的搜索题目.从小到大枚举拼成的新木棍长度,每次枚举进行一次深搜.这题关键是如何剪枝. 1.当枚举的长度不能整除总长度的时候,剪枝:(这个很显然) 2.先将木棍从长到短排序,枚举时先尝试长的木棍.(先枚举长的可以使得搜索深度不至于过深) 3.深搜时,不要企图通过换掉一个新木棍的第一根来改变失败的局面(换掉第一根A,那么A也会在以后的新木棍中被使用,但是已经证明了A无法拼成了,所以不必再尝试下去了)

hdu 1518 Square(深搜+剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! 1 #include <iostream> 2 #include <cstdio> 3 #include<algorithm> 4 #include <cstring> 5 using namespace std; 6 int ap[30],visit[30]

迭代深搜

迭代深搜简单来说就是限制深度的深搜,这样就可以避免像广搜一样占用大量空间,又可以像广搜找到最佳的路径. 两道例题 1.埃及分数 #include<cstdio> #include<set> #include<cstring> using namespace std; const int N = 10; typedef long long LL; set<LL>s; LL now[N], pre[N]; bool flag; LL gcd(LL a, LL b

poj1190 生日蛋糕(深搜+剪枝)

题目链接:poj1190 生日蛋糕 解题思路: 深搜,枚举:每一层可能的高度和半径 确定搜索范围:底层蛋糕的最大可能半径和最大可能高度 搜索顺序:从底层往上搭蛋糕,在同一层尝试时,半径和高度都是从大到小试 剪枝: ①已建好的面积已经超过目前求得的最优表面积,或者预见到搭完后面积一定会超过目前最优表面积,则停止搭建(最优性剪枝) ②预见到再往上搭,高度已经无法安排,或者半径无法安排,则停止搭建(可行性剪枝) ③还没搭的那些层的体积,一定会超过还缺的体积,则停止搭建(可行性剪枝) ④还没搭的那些层的

hdu1518(Square)深搜+剪枝

点击打开杭电1518 Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square? Input The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20,

ACM 海贼王之伟大航路(深搜剪枝)

"我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的岛屿. 因为伟大航路上的气候十分异常,所以来往任意两个岛屿之间的时间差别很大,从A岛到B岛可能需要1天,而从B岛到A岛则可能需要1年.当然,任意两个岛之间的航行时间虽然差别很大,但都是已知的. 现在假设路飞一行从罗格镇(起点)出发,遍历伟大航路中间所有的岛屿(但是已经经过的岛屿不能再次经过),最后到达拉夫德鲁

hdu 1455 sticks(经典深搜+剪枝技巧)

 题意:有一堆的木棒,长度不一,它们是有一些整齐的木棒截断而成的,求最小的木棒原始长度. 思路很简单深搜,但是直接深搜的话会tle,首先可以对木棒长度进行排序从大到小,优先使用长度长的木棒,加入当前长度不符合,考虑下一个木棒 其次如果长度为零的时候选择木棒失败,那么直接退出,实测加上这一剪枝就可以ac,这一剪枝可以帮助我们尽可能的在靠近树根处剪枝,所以优化效果很明显. 然后是如果这次选择的木棒长度和上次失败时的一样,那么剪枝. #include<cstdio> #include<cs