埃及分数问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了埃及分数问题相关的知识,希望对你有一定的参考价值。

对于一个分数a/b(a!=1),将它表示为1/x + 1/y + 1/z ……的形式,x,y,z……互不相同

多解取加数少的,

加数相同时,取最小的分数最大的

 

最容易的搜索:确定加数的个数,分母大小范围

题目没有给出任何搜索限制条件,那就自己加

挖掘题目,可以分析得出分母搜索下限:满足1/x<=a/b的最小的x

分母上限,无

限制加数个数:迭代加深搜索

限制搜索顺序:强制递增搜索

 

迭代加深搜索,加上一个估价函数(就是剪枝)变成IDA*

 

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
int maxd;
int v[101],ans[101];
int get_first(int a,int b)
{
    for(int i=1;;i++)
     if(1.0/i<=a*1.0/b) return i;
}
bool better(int d)
{
    for(int i=d;i>=0;i--)
     if(v[i]!=ans[i]) return ans[i]==-1 || v[i]<ans[i];
    return false;
}
bool dfs(int d,int from,LL aa,LL bb)
{
    if(d==maxd)
    {
        if(bb%aa) return false;
        v[d]=bb/aa;
        if(better(d)) memcpy(ans,v,sizeof(*ans)*(d+1));
        return true;
    }
    bool ok=false;
    from=max(from,get_first(aa,bb));
    for(int i=from;;i++)
    {
        if(bb*(maxd-d+1)<=i*aa) break;
        v[d]=i;
        LL b2=bb*i,a2=aa*i-bb,g=__gcd(b2,a2);
        if(dfs(d+1,i+1,a2/g,b2/g)) ok=true;
    }
    return ok;
}
int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        if(!a) return 0;
        for(maxd=1;;maxd++)
        {
            memset(ans,-1,sizeof(ans));
            if(dfs(0,get_first(a,b),a,b))  
            {
                for(int i=0;i<=maxd;i++) printf("1/%d ",ans[i]);
                puts("");
                break;
            }
        }
    }    
} 

 

以上是关于埃及分数问题的主要内容,如果未能解决你的问题,请参考以下文章

埃及分数

题解 埃及分数

埃及分数问题(JLNUOJ 2372)

[题解]「一本通 1.3 练习 1」埃及分数

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

埃及分数,迭代加深