埃及分数(迭代深搜)

#include<bits/stdc++.h>
using namespace std;
long long ch,mo;
int dep;
long long ans[1000],s[1000];
int gcd(long long a,long long b)
{
    return b==0?a:gcd(b,a%b);
}
void outp()
{
    if(ans[dep]>s[dep])
    {
        for(int i=1;i<=dep;i++) ans[i]=s[i];
    }
}
void dfs(long long zi,long long mu,int d)
{
    long long a,b,w;
    if(d==dep)
    {
        s[d]=mu;
        if((zi==1)&&s[d]>s[d-1]) outp();
        return;
    }
    for(int i=max(s[d-1]+1,mu/zi+1);i<(dep-d+1)*mu/zi;i++)//此步骤着重理解,
    {                                            // 由上一步和dep深度决定i的取值范围
        b=mu*i/gcd(mu,i);
        a=b*zi/mu-b/i;
        w=gcd(a,b);
        a/=w;b/=w;
        s[d]=i;
        dfs(a,b,d+1);
    }
}
int main(){
    scanf("%lld%lld",&ch,&mo);
    int i=gcd(ch,mo);
    ch/=i;
    mo/=i;
    for(dep=2;;dep++)
    {
        ans[1]=0;
        s[0]=0;
        ans[dep]=200000000;
        dfs(ch,mo,1);
        if(ans[1]!=0) break;
    }
    for(int j=1;j<=dep;j++)
    {
        printf("%d ",ans[j]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/719666a/p/9507714.html

时间: 2024-11-07 21:22:31

埃及分数(迭代深搜)的相关文章

一本通例题埃及分数—题解&amp;&amp;深搜的剪枝技巧总结

一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化过程就像将搜索树上没用的枝条剪下来,因此搜索的优化过程又叫剪枝.剪枝的实质就是通过判断决定是否要沿当前枝条走下去. 二.搜索的剪枝必需遵循三个原则: 1.正确性(不能把正解排除,要不然搜什么呢?)2.准确性(尽可能把不能通向正解的枝条剪去)3.高效性(因为在每个枝条上都要进行一次判断,如果判断的复杂

迭代深搜

迭代深搜简单来说就是限制深度的深搜,这样就可以避免像广搜一样占用大量空间,又可以像广搜找到最佳的路径. 两道例题 1.埃及分数 #include<cstdio> #include<set> #include<cstring> using namespace std; const int N = 10; typedef long long LL; set<LL>s; LL now[N], pre[N]; bool flag; LL gcd(LL a, LL b

UVA1374 - Power Calculus(迭代深搜+剪枝)

题目链接 题意:给出x和正整数n,问最少需要几次乘除法 可以得到n = x^m 思路:其实是关于指数的操作,即从1到m最少的步数.我们可以先确定最少步数m,然后进行迭代,迭代的过程也就是判断通过相加减所得到的数可以在m次操作中等于n,如果符合,m即为最小步数,如果不符合,m++,进行下一次迭代.迭代过程中要注意剪枝,即剩余的次数如果每次都是取最大值相加还是比n小的话,就直接跳出. 代码: #include <iostream> #include <cstdio> #include

bzoj 1085骑士精神 迭代深搜

题目传送门 题目大意:给出一幅棋盘,问能否复原,中文题面,不做解释. 思路:第一次写迭代深搜的题目,这道题还是挺经典的.这道题的状态很明显的每多搜一层就是多八倍,非常的多,而且又是t组输入,所以必定有很多点是在深层次的,所以用迭代深搜,这就是很多组数据在很浅的层就得到了答案,不需要多做了,而有一些样例则是确实会重复计算(答案层次比较深的时候),但是此时浪费的时间和之前节约的时间已经不是一个数量级的了,故用迭代深搜,这也是迭代深搜的标志性功能. 但是光迭代深搜没有用,还需要一个估价函数来剪枝,这里

POJ 1129-Channel Allocation(四色定理+迭代深搜)

题目链接:传送门 题意:n个信号站,给出连接情况,要用信号覆盖所有信号站,要求相连的信号站不能用同一个信号. 等价问题==无向图染色==四色定理(每个平面地图都可以只用四种颜色来染色,而且没有两个邻接的区域颜色相同.已证明) 思路:深搜一条路(枚举颜色,判断当前点用已有的颜色能不能染,如不能则加一种颜色,判断强判就行了),搜到头答案就出来了..然后返回就可以了 注意单复数.. #include <algorithm> #include <iostream> #include <

埃及数字(迭代深搜)

题目描述 Description 在古埃及,人们使用单位分数的和(形如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 +

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=g

UVA - 1374 Power Calculus 迭代深搜

题目大意:问从1变到n至少需要多少步.变换规则如下 1.变化过程中的中间结果可以任意使用 2.每次只能挑选两个数进行加减 解题思路:先算一下至少需要多少步,然后在如果在当前步数下无法到达结果的话,就当前步数加1,继续搜索下去 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 1010 int num[maxn], cnt, n ,MIN_dep

poj 3134 Power Calculus iddfs(迭代深搜)

iddfs入门题. //poj 3134 //sep9 #include <iostream> using namespace std; int n,deep; int a[30]; bool iddfs(int pos) { int t; if(pos>deep) return false; if(a[pos]<<(deep-pos)<n) return false; if(a[pos]==n) return true; for(int i=1;i<=pos;+