POJ-3134-Power Calculus(迭代加深DFS)

Description

Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications:

x2 = x × xx3 = x2 × xx4 = x3 × x, …, x31 = x30 × x.

The operation of squaring can be appreciably shorten the sequence of multiplications. The following is a way to compute x31 with eight multiplications:

x2 = x × xx3 = x2 × xx6 = x3 × x3x7 = x6 × xx14 = x7 × x7x15 = x14 × xx30 = x15 × x15x31 = x30 × x.

This is not the shortest sequence of multiplications to compute x31. There are many ways with only seven multiplications. The following is one of them:

x2 = x × x, x4 = x2 × x2x8 = x4 × x4x8 = x4 × x4x10 = x8 × x2x20 = x10 × x10x30 = x20 × x10x31 = x30 × x.

If division is also available, we can find a even shorter sequence of operations. It is possible to compute x31 with six operations (five multiplications and one division):

x2 = x × xx4 = x2 × x2x8 = x4 × x4x16 = x8 × x8x32 = x16 × x16x31 = x32 ÷ x.

This is one of the most efficient ways to compute x31 if a division is as fast as a multiplication.

Your mission is to write a program to find the least number of operations to compute xn by multiplication and division starting with x for the given positive integer n. Products and quotients appearing in the sequence
should be x to a positive integer’s power. In others words, x?3, for example, should never appear.

Input

The input is a sequence of one or more lines each containing a single integer nn is positive and less than or equal to 1000. The end of the input is indicated by a zero.

Output

Your program should print the least total number of multiplications and divisions required to compute xn starting with x for the integer n. The numbers should be written each in a separate line without any superfluous
characters such as leading or trailing spaces.

Sample Input

1
31
70
91
473
512
811
953
0

Sample Output

0
6
8
9
11
9
13
12

Source

Japan 2006

思路:用一个数组存每一次操作之后得到的数,剪下枝,迭代加深即可。详见代码。

#include <stdio.h>
#define max(A,B)(A>B?A:B)

int n,dep,num[15];

bool dfs(int cnt,int x)//x是上一次操作之后得到的最大的数
{
    if(num[cnt]==n) return 1;

    if(cnt>=dep) return 0;

    x=max(x,num[cnt]);

    if(x*(1<<(dep-cnt))<n) return 0;//如果最大的数都不能得到n就直接返回

    for(int i=0;i<=cnt;i++)
    {
        num[cnt+1]=num[cnt]+num[i];

        if(dfs(cnt+1,x)) return 1;

        if(num[cnt]>num[i]) num[cnt+1]=num[cnt]-num[i];
        else num[cnt+1]=num[i]-num[cnt];

        if(dfs(cnt+1,x)) return 1;
    }

    return 0;
}

int main()
{
    while(~scanf("%d",&n) && n)
    {
        if(n==1) printf("0\n");
        else
        {
            num[0]=1;

            for(dep=1;;dep++)
            {
                if(dfs(0,1)) break;
            }

            printf("%d\n",dep);
        }
    }
}

POJ-3134-Power Calculus(迭代加深DFS),布布扣,bubuko.com

时间: 2024-08-05 15:20:54

POJ-3134-Power Calculus(迭代加深DFS)的相关文章

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

题目大意:略 题目里所有的运算都是幂运算,所以转化成指数的加减 由于搜索层数不会超过$2*log$层,所以用一个栈存储哪些数已经被组合出来了,不必暴力枚举哪些数已经被搜出来了 然后跑$iddfs$就行了 可以加一个剪枝,设你选择的最大迭代深度为K,现在如果当前组合出的数$x$,满足$x*2^{K-dep}<n$,说明$n$一定无法被$x$组合出来(即自己不断加自己),$x$对于答案是一定无意义的,就跳出 1 #include <queue> 2 #include <cstdio&g

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

迭代加深 //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 (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>

构造数列 迭代加深dfs

[题目描述] 请构造一个尽量短的序列 A,长度为 len,一开始会给你一个正整数 n, 满足以下条件: A[1]=1 A[len]=n A[i]>A[i-1]                       (len>=i>=2) A[x]=A[i]+A[j]           (1<=i,j<x) [输入文件] 此题有多组数据,每行一个正整数n, 输入以 0 结尾 [输出文件] 每行 len 个正整数,为A 序列 [输入样例1]                        

[迭代加深dfs] zoj 3768 Continuous Login

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3768 Continuous Login Time Limit: 2 Seconds      Memory Limit: 131072 KB      Special Judge Pierre is recently obsessed with an online game. To encourage users to log in, this game wi

【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