迭代加深搜索初步

迭代加深搜索:这是一种类似广搜的深搜,但是它不需要广搜如此大的空间,它的空间与深搜的空间一样,那么这时问题就来了,迭代深搜怎么实现呢?
我们需要用到一个dep变量(名字可以自己取),用于枚举迭代深搜的深度,搜索
那么从这个图中不难看出,dep枚举的是搜索的深度,一般性一开始都定为1(你也可以随便定一个数),每次累加一般累加1。
迭代加深的应用主要在于这么一道家喻户晓的题目:埃及分数
这道题首先看上去没有什么思路,如果广搜空间必然承受不了,单一的深搜时间又太慢,不难想到要用一些带技巧的搜索,可是如果只是简单的剪枝,能剪下复杂度吗?答案是否定的,唯一的办法就是A*或迭代深搜,这里我们主要讲迭代深搜!

#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<iostream>
using namespace std;
#define up(a,b,c) for(a=b;a<=c;a++)
#define ll long long
const int INF= ~0U>>1;
ll dep=1,ans[11],d[11],flag;
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
void dfs(ll a,ll b,int sum){
    ll i;
    if(sum>dep)return;
    if(a==1 && b>d[sum-1]){
        d[sum]=b;
        if(!flag || d[sum]<ans[sum]){
            memcpy(ans,d,sizeof(d));
        }
        flag=1;
        return;
    }
    ll l=b/a;
    if(l<=d[sum-1])l=d[sum-1]+1;
    ll r=(dep-sum+1)*b/a;
    if(r>INF)r=INF-1;
    if(flag && r>=ans[dep])r=ans[dep]-1;
    up(i,l,r){
        d[sum]=i;
        ll gc=gcd(i*a-b,b*i);
        dfs((i*a-b)/gc,b*i/gc,sum+1);
    }
}
int main(){
    int i,j,k,n,m;
    long long a,b;
    cin>>a>>b;
    ll c=gcd(a,b);
    a/=c;b/=c;d[0]=1;
    if(a==1){
        cout<<b<<endl;return 0;
    }
    while(dep<=10){
        dfs(a,b,1);
        if(flag){
            for(i=1;i<=dep;i++)
                printf("%lld ",ans[i]);
            puts("");
            return 0;
        }
        dep++;
    }
    return 0;
}

这是笔者的代码,不难理解其中的一些关键部分,这个里面还有一些重要的剪枝,像如果枚举到了最后一个数,那么它必定是a/b-前面数的埃及分数和!知道了这个条件有如神助,当然,还有别的剪枝方法,如果想了解剪枝请关注以后的文章(与生日蛋糕有关)!

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值