首页 > 其他 > 详细

埃及分数问题

时间:2017-08-03 21:24:15      阅读:162      评论:0      收藏:0      [点我收藏+]

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

 

埃及分数问题

原文:http://www.cnblogs.com/TheRoadToTheGold/p/7281727.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!