首页 > 代码库 > 埃及分数问题

埃及分数问题

对于一个分数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;            }        }    }    } 

 

埃及分数问题