zoukankan      html  css  js  c++  java
  • UVa 1374 Power Calculus (IDA*或都打表)

    题意:给定一个数n,让你求从1至少要做多少次乘除才可以从 x 得到 xn

    析:首先这个是幂级的,次数不会很多,所以可以考虑IDA*算法,这个算法并不难,难在找乐观函数h(x),

    这个题乐观函数可以是当前最大数*2maxd - d 小于n,回溯。很好理解,最大的数再一直乘2都达不到,最终肯定达不到。

    再就是应该先试乘再试除,还有不要出现负整数。我测了不少知道应该是13次最多,所以这也是一个优化。

    为了追求速度,也可以先1~1000的数打表。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 1000 + 5;
    int maxd, n, a[maxn];
    
    
    bool dfs(int d, int num, int cur){
        if(d == maxd){
            if(n == cur)   return true;
            return false;
        }
    
        int m = 0;
        for(int i = 0; i < num; ++i) m = max(m, a[i]);
        if(m * (1 << (maxd - d)) < n)  return false;//回溯
    
        for(int i = num-1; i >= 0; --i){
            a[num] = cur + a[i];   ++num;//乘法
            if(dfs(d+1, num, cur+a[i]))  return true;
            a[num-1] = abs(cur - a[i]);//除法
            if(dfs(d+1, num, abs(cur-a[i])))  return true;
            --num;
        }
        return false;
    }
    
    int main(){
        while(scanf("%d", &n) == 1 && n){
            for(maxd = 0; maxd < 13; ++maxd){
                a[0] = 1;
                if(dfs(0, 1, 1)) break;
            }
            printf("%d
    ", maxd);
        }
        return 0;
    }
    

    下面是打表的代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    const int ans[]={0,1,2,2,3,3,4,3,4,4,5,4,5,5,5,4,5,5,6,5,6,6,6,5,6,6,6,6,7,6,6,5,6,6,
    7,6,7,7,7,6,7,7,7,7,7,7,7,6,7,7,7,7,8,7,8,7,8,8,8,7,8,7,7,6,7,7,8,7,8,8,8,7,8,8,8,8,
    8,8,8,7,8,8,8,8,8,8,9,8,9,8,9,8,8,8,8,7,8,8,8,8,9,8,9,8,9,9,9,8,9,9,9,8,9,9,9,9,9,9,9,8,
    9,9,9,8,9,8,8,7,8,8,9,8,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,10,9,9,9,9,9,9,9,9,
    8,9,9,9,9,9,9,10,9,10,9,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,9,10,9,9,9,9,8,
    9,9,9,9,10,9,10,9,10,10,10,9,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,
    10,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,
    10,9,10,9,9,8,9,9,10,9,10,10,10,9,10,10,11,10,11,10,10,9,10,10,11,10,11,10,10,10,
    10,10,10,10,10,10,10,9,10,10,10,10,10,10,11,10,10,10,11,10,11,11,11,10,11,10,11,10,
    11,10,11,10,11,10,10,10,10,10,10,9,10,10,10,10,10,10,11,10,11,10,11,10,11,11,11,10,11,11,11,
    10,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,
    10,11,11,11,10,11,11,11,10,11,10,11,10,10,10,10,9,10,10,10,10,11,10,11,10,11,11,11,10,11,
    11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,
    11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,
    11,11,11,11,11,11,11,12,11,12,11,11,11,12,11,12,11,11,11,11,11,11,11,11,11,11,10,11,11,
    11,11,11,11,11,11,11,11,12,11,12,11,11,10,11,11,12,11,12,11,11,10,11,11,11,10,11,10,10,9,10,
    10,11,10,11,11,11,10,11,11,12,11,12,11,11,10,11,11,12,11,12,12,11,11,12,12,12,11,12,11,11,10,
    11,11,12,11,12,12,12,11,11,12,12,11,12,11,12,11,11,11,12,11,12,11,11,11,12,11,11,11,11,11,11,10,11,
    11,11,11,11,11,12,11,11,11,12,11,12,12,12,11,12,11,12,11,12,12,12,11,12,12,12,12,12,
    12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,11,12,11,
    12,11,11,11,11,11,11,10,11,11,11,11,11,11,12,11,12,11,12,11,12,12,
    12,11,12,12,12,11,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,
    12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,
    12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
    12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,11,12,12,12,11,12,
    11,12,11,11,11,11,10,11,11,11,11,12,11,12,11,12,12,12,11,12,12,12,11,12,12,12,12,
    12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,13,12,12,12,
    12,11,12,12,12,12,13,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,
    12,12,12,12,12,13,12,12,12,13,12,13,12,12,12,13,12,12,12,12,12,12,11,12,12,12,12,12,
    12,13,12,12,12,13,12,13,12,12,12,13,12,13,12,13,12,12,12,12,12,12,12,12,12,
    12,11,12,12,12,12,12,12,12,12,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,
    13,13,12,13,13,13,12,13,12,13,12,13,13,13,12,13,13,13,12,13,12,13,12,12,12,13,12,
    13,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,13,12,13,12,
    12,12,12,12,13,12,13,13,13,12,13,13,13,12,13,12,12,11,12,12,13,12,13,13,13,12};
    
    int main()
    {
        int n;
        while(scanf("%d",&n) == 1 && n)
            printf("%d
    ", ans[n-1]);
        return 0;
    }
    

     可以看到最大才是13,次数不会很多。

  • 相关阅读:
    javascript中的预编译问题
    五环
    两列布局
    定位以及z-index
    [vijos1234]口袋的天空<最小生成树>
    [讲解]prim算法<最小生成树>
    [noip模拟]B<构造>
    [JZOJ5343]健美猫<模拟>
    [noip模拟]心<并查集>
    [noip模拟]种花<快速幂+结论>
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5599275.html
Copyright © 2011-2022 走看看