UVa1374快速幂运算迭代深搜法

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41552


本题不算太难,但我刚开始的时候居然理解错了。那句“问最少需要几次乘除法可以从X得到X^n?“,从这句话中你一定要能理解他是从一开始,每次从之前的数据中抽出两个数来进行运算,之前我就一直在纠结,X他又没给我,我怎么求?额,智商不够没办法,努力吧。好废话不扯了,进入正题。


解题思路:

本题我们要求的是最短路径,一想到求最短路径无非就是BFS或者就是迭代加深搜,由于本题数据还是有些大,所以用迭代加深搜,外加启发式函数。迭代加深搜都是固定思维,我们先来说说启发式函数吧。就是估计以后的每次运算都取最大值假如还低于N,那么就返回false。其实是关于指数的操作,即从1到m最少的步数。我们可以先确定最少步数m,然后进行迭代,迭代的过程也就是判断通过相加减所得到的数可以在m次操作中等于n,如果符合,m即为最小步数,如果不符合,m++,进行下一次迭代。迭代过程中要注意剪枝,即剩余的次数如果每次都是取最大值相加还是比n小的话,就直接跳出。

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

const int maxans = 13;

int n,ans[maxans+1];

bool dfs(int d,int maxd){
    if(ans[d] == n)return true;//找到答案
    if(d == maxd)return false;

    int maxv = ans[0];

    for(int i = 1;i <= d; i++)maxv = max(maxv,ans[i]);//找出之前的最大值,用来写启发式函数
    if((maxv << (maxd-d)) < n) return false;//如果之后的全取最大值仍然小于n,则返回假
    for(int i = d;i >= 0; i--){
        ans[d+1] = ans[d] + ans[i];
        if(dfs(d+1,maxd))return true;
        ans[d+1] = ans[d] - ans[i];
        if(dfs(d+1,maxd))return true;
    }
      return false;
}

int solve(){
    if(n == 1)return 0;
    ans[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){
        printf("%d\n",solve());
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值