【UVa】1374 Power Calculus(IDA*)

题目

题目
?



?

分析

IDA*大法好,抄了lrj代码。
?



?

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxans=14;

int n,a[maxans+1];

bool dfs(int d,int maxd)
{
    if(a[d] == n) return true;
    if(d == maxd) return false;

    int maxv=a[0];
    for(int i=1; i<=d; i++) maxv=max(maxv, a[i]);
    if( (maxv << (maxd-d)) < n) return false;

    for(int i=d; i>=0; i--)
    {
        a[d+1]=a[d]+a[i];
        if(dfs(d+1 , maxd)) return true;
        a[d+1] = a[d] - a[i];
        if(dfs(d+1 , maxd)) return true;
    }
    return false;
}

int solve(int n)
{
    if(n==1) return 0;
    a[0]=1;
    for(int maxd=1; maxd < maxans; maxd++)
        if(dfs(0,maxd)) return maxd;
    return maxans;
}

int main()
{
    while( scanf("%d",&n)==1 && n!=0)
        printf("%d\n",solve(n));
    return 0;
}

原文地址:https://www.cnblogs.com/noblex/p/8119357.html

时间: 2024-10-07 16:31:33

【UVa】1374 Power Calculus(IDA*)的相关文章

【UVA】10404-Bachet&#39;s Game(动态规划)

如果d[i]是必胜态,那么d[i + V[j]]一定是必败态,反之亦然. 用d[i]代表棋子为i个是否为必胜态. 边界条件是d[i] = 1; 14139291 10404 Bachet's Game Accepted C++ 0.662 2014-09-03 09:44:48 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vecto

【UVA】11181 - Probability|Given(条件概率)

一道条件概率题,数学烂真的伤不起,一开始都不知道怎么求条件概率. P(e) = p(e|E)/p(E). 用e出现的情况的概率,除以所有情况出现的概率,递归枚举每个人是否买东西了. 14026058 11181 Probability|Given Accepted C++ 0.102 2014-08-12 08:25:51 效率可能有点差. #include<cstdio> #include<cstring> #include<iostream> #include<

UVa 1374 Power Calculus (IDA*或都打表)

题意:给定一个数n,让你求从1至少要做多少次乘除才可以从 x 得到 xn. 析:首先这个是幂级的,次数不会很多,所以可以考虑IDA*算法,这个算法并不难,难在找乐观函数h(x), 这个题乐观函数可以是当前最大数*2maxd - d 小于n,回溯.很好理解,最大的数再一直乘2都达不到,最终肯定达不到. 再就是应该先试乘再试除,还有不要出现负整数.我测了不少知道应该是13次最多,所以这也是一个优化. 为了追求速度,也可以先1~1000的数打表. 代码如下: #include <iostream>

【Uva11212】 Editing a Book(IDA*)

[题意] 有n个数字的全排列,每次可以剪切一段粘贴到某个位置.问最后变成升序最少多少步. 如"{2,4,1,5,3,6}要2步 {3,4,5,1,2}只要一步 [分析] 迭代深搜真的AC了也觉得慌= = [其实看到这题不应该想到宽搜么??? 全排列只有9!=362880个 这题的IDA*的估价函数特别机智: n<=9,最多2需要8步,深度上限为8. 考虑后继不正确的赎回自个数h,可以证明每次剪切时候h最多减少3,因此当3*d+h>3*maxd时可以剪枝. [证明上面那个画一下就知道,

【UVA】11796 - Dog Distance(相对运动)

因为a,b是同时出发,同时达到,但是他们的速度不一定一样,所以我们可以设他们的速度为La,Lb(La,Lb为a,b狗的总路程) 那么,如何a,b都是沿着直线运动的时候如何求他们之间的最短最长距离呢? 因为运动都是相对的,所以我们可以把a看成不懂的,而b相对于a的移动方向就是Vb - Va,因此就可以看成a和线段 b + (Vb -Va)之间的关系了 至于方向Va,Vb向量怎么求,我们可以利用单位向量 X 移动时间 X 移动速度 得到. 经典的一道题,顺便还修复了一个模板的BUG: 1412818

【UVa】Partitioning by Palindromes(dp)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=27&page=show_problem&problem=2549 设w[i,j]为i-j能分割成的最少回文串 f[i]为前i个字符能够分成的最少回文串 w[i,j]=1 当w[i+1,j-1]==1 && s[i]==s[j] 或 i==j-1 && s[i]==s[j] w[i,j]=

【UVa】439 Knight Moves(dfs)

题目 题目 ? ? 分析 没有估价函数的IDA...... ? ? 代码 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int q,dx[10]={2,2,-2,-2,1,-1,1,-1},dy[10]={1,-1,1,-1,2,2,-2,-2},ans=1<<15; bool vis[11][11]; int x1,y1,x2,y2; bool

【UVa】1600 Patrol Robot(dfs)

题目 题目 ? ? 分析 bfs可以搞,但是我还是喜欢dfs,要记忆化不然会T ? ? 代码 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF=1<<25; int k,n,m,map[25][25],dx[10]={1,-1,0,0},dy[10]={0,0,1,-1},ans; int vis[25][25][25];

【UVa】Headmaster&#39;s Headache(状压dp)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1758 晕....状压没考虑循环方向然后错了好久.. 这点要注意...(其实就是01背包变成了完全背包QAQ 我们将课程拆成两个点,然后状压 那么答案就是(1<<(s<<1))-1 转移就不说了,,,,,太简单.. #include <cstdio> #in