• 埃及分数


    https://loj.ac/problem/10022

    题目描述

      对于形如(frac{1}{n}) ((n)为正整数)称为单位分数,给出(a)(b),表示分数(frac{a}{b})求最少可用几个单位分数表示,给出方案。

    思路

      这道题的难点主要在于对分数的处理和枚举边界的决定。首先我们先可以确定(dfs)的大致框架和(dfs)的内容。由于一个分数有无数多种拆分方式,而我们需要的仅仅是长度最短和最小分数最大的方案,因此可以采用迭代加深搜索,枚举这个分数由几个单位分数组成。所以我们的(dfs)需要存储这几个信息:当前枚举到第几个答案,枚举的下界,用(p)(q)两个变量存储分数。我们先考虑最初的枚举下界,显然,如果(a|b),那么可直接输出答案;否则,我们可以从(frac{a}{b}+1)开始枚举,因为这是小于它的最大单位分数。所以我们可以每一次都处理一遍(frac{p}{q})的下界,枚举每个单位分数,再减去该单位分数进行枚举。不过我们还未处理其上界,显然,如果剩下的所有数都为(frac{1}{i})和都达不到(frac{p}{q})就可以结束循环。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll s[10100],ans[10100],lim;
    ll gcd(ll a,ll b)
    {
        return a%b==0?b:gcd(b,a%b);
    }
    bool check()
    {
    /*    for(ll i=lim;i>0;i--)
            printf("%lld ",s[i]);
        printf("
    ");*/
        for(ll i=lim;i>0;i--)
            if(s[i]!=ans[i])return ans[i]==-1||s[i]<ans[i];
        return 0;
    }
    bool dfs(ll dep,ll from,ll p,ll q)
    {
        if(dep==lim)
        {
            if(q%p!=0)return 0;
            s[dep]=q/p;
            if(check())
            {
                for(int i=1;i<=dep;i++)
                    ans[i]=s[i];
            }
            return 1;
        }
        else
        {
            bool f=0;
            from=max(from,q/p+1);
            for(ll i=from;;i++)
            {
                if(q*(lim+1-dep)<=i*p)break ;
                s[dep]=i;
                ll pp=p*i-q;
                ll qq=q*i;
                ll g=gcd(pp,qq);
                if(dfs(dep+1,i+1,pp/g,qq/g))f=1;
            }
            return f;
        }
        
    }
    int main() 
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(b%a==0)
            printf("%lld",b/a);
        else
        {
            for(lim=1;;lim++)
            {
                memset(ans,-1,sizeof(ans));
                if(dfs(1,b/a+1,a,b))break ;
            }
            for(ll i=1;i<=lim;i++)
                printf("%lld ",ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    HANDLE CreateThread()
    偷懒的一天-jQuery之事件与应用
    web进阶之jQuery操作DOM元素&&MySQL记录操作&&PHP面向对象学习笔记
    无聊的周五晚上
    闲里偷闲
    被蚊子和自己搞毁的一天
    数据库有点意思
    周一周一周。。一
    无聊到周六的教研室
    1.Nginx相关概念
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11760645.html
Copyright © 2020-2023  润新知