Loj10022 埃及分数(迭代加深搜索IDDFS)

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;

ll depth,a,b,flag,ans[100005],nans[100005];

inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; }

inline void yuefen(ll &a,ll &b){ll eaa=gcd(a,b);a/=eaa;b/=eaa;}

inline void dfs(ll now,ll shen_fz,ll shen_fm,ll last_fm){
    yuefen(shen_fz,shen_fm);//在上面统一约分多省事啊哈哈哈
    if(now==depth){
        if(shen_fz==1&&shen_fm>last_fm){
            if(flag&&shen_fm>=ans[depth])return;//要比较取优,因为最大的分母是算出来的不是搜出来的
            nans[depth]=shen_fm;
            flag=1;
            memcpy(ans,nans,sizeof(nans));
        }
        return;
    }
    for(ll i=last_fm+1;i<=ceil((double)(depth-now+1)*shen_fm/shen_fz);i++){
            //i=last_fm+1使搜出来的分母递增,所以说都是要这样搜啊QAQ
            //(depth-now+1)*shen_fm/shen_fz是趋近的最大值,即限制能否在depth内把shen的分数拆分完
            //其实好像可以判断一下就是(i>=shen_fm/shen_fz才可以),跟最后一个注释同理,亲测确实快一点
        nans[now]=i;
        dfs(now+1,shen_fz*i-shen_fm,shen_fm*i,i);
    }
}

int main(){
    scanf("%I64d%I64d",&a,&b);//好吧其实在loj上忘了改成lld
    while(++depth){
        dfs(1,a,b,b/a-1);//b/a是第一个分母的最小值,第一个分母不用从1开始搜的
        if(flag){
            for(ll i=1;i<=depth;i++)printf("%I64d ",ans[i]);
            return 0;
        }
    }
}

好吧算是比较易懂了

原文地址:https://www.cnblogs.com/Y15BeTa/p/loj10022.html

时间: 2024-08-11 19:39:53

Loj10022 埃及分数(迭代加深搜索IDDFS)的相关文章

“埃及分数”问题浅谈对迭代加深搜索的理解

迭代加深搜索(IDDFS)的思想 迭代加深搜索一般用来求解状态树"非常深",甚至深度可能趋于无穷,但是"目标状态浅"的问题.如果用普通的DFS去求解,往往效率不够高.此时我们可以对DFS进行一些改进.最直观的一种办法是增加一个搜索的最大深度限制maxd,一般是从1开始.每次搜索都要在maxd深度之内进行,如果没有找到解,就继续增大maxd,直到成功找到解,然后break. 如下图所示,如果用DFS,需要15步才能找到结点3,但是用迭代加深搜索,很快即可找到结点3.

【迭代加深搜索】埃及分数问题

谢谢阿苏~http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5856756 [迭代加深搜索(ID,iterative deepening)]:从小到大枚举上限maxd,每次执行只考虑深度不超过maxd的结点. ------对于可以用回溯法求解但解答树的深度没有明显上限的题目,可以考虑ID算法: ------优点:它主要是在递归搜索函数的开头判断当前搜索的深度是否大于预定义的最大搜索深度,如果大于,就退出这一层的搜索,如果不大于,就

vijos1308 埃及分数(迭代加深搜索)

题目链接:点击打开链接 题目描述: 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的.对于一个分数a/b,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好. 如:19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6

埃及分数问题_迭代加深搜索_C++

一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19/45=1/3 + 1/12 + 1/180 二.迭代加深搜索 迭代加深搜索可以看做带深度限制的DFS. 首先设置一个搜索深度,然后进行DFS,当目前深度达到限制深度后验证当前方案的合理性,更新答案. 不断调整搜索深度,直到找到最优解. 三.埃及分数具体实现 我们用dep限制搜索层数,先从2开始,每

IDDFS(迭代加深搜索)精选题and总结

引入:什么是IDDFS? 在计算机科学中,迭代深化搜索(iterative deepening search)或者更确切地说迭代深化深度优先搜索 (iterative deepening depth-first search (IDS or IDDFS)) 是一个状态空间(状态图)搜索策略.在这个搜索策略中,一个具有深度限制的深度优先搜索算法会不断重复地运行,并且同时放宽对于搜索深度的限制,直到找到目标状态.IDDFS 与广度优先算法是等价的,但对内存的使用会少很多:在每一步迭代中,它会按深度优

搜索专题小结:迭代加深搜索

迭代加深搜索 迭代加深搜索(Iterative Deepening Depth-First Search, IDDFS)经常用于理论上解答树深度上没有上界的问题,这类问题通常要求出满足某些条件时的解即可.比如在"埃及分数"问题中要求将一个分数a/b分解成为若干个形如1/d的加数之和,而且加数越少越好,如果加数个数相同,那么最小的分数越大越好.下面总结一下该方法的一般流程: (1)概述:迭代加深搜索是通过限制每次dfs的最大深度进行的搜索.令maxd表示最大的搜索深度,那么dfs就只能在

uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索

迭代加深搜索 自己看的时候第一遍更本就看不懂..是很水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题并且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的见解, 真的是很有帮助,也许自己想要想很久才能想明白,还会很痛苦,稍微问一下别人的想法,点上一个方向,剩下的自己就能想得明白了. 迭代加深. 把answer(需要的步数或其他)在主函数里面从零往上递加,此之谓 "层数",亦可谓之"深度".用书上的话就是: 从小到大枚举深度

Codevs 四子连棋 (迭代加深搜索)

题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Input Description 从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用

C++解题报告 : 迭代加深搜索之 ZOJ 1937 Addition Chains

此题不难,主要思路便是IDDFS(迭代加深搜索),关键在于优化. 一个IDDFS的简单介绍,没有了解的同学可以看看: https://www.cnblogs.com/MisakaMKT/articles/10767945.html 我们可以这么想,设当前规定长度为M,题目要求得出的数为N. 在搜索中,当前的步数为step,当前的数列为 数组a. 首先来确定思路,便是在以得出的数列a中枚举每两个数相加得出sum,然后继续搜索下一步. 初步的代码便是: void iddfs(int x) { for