埃及分数问题
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; } } } }
以上是关于埃及分数问题的主要内容,如果未能解决你的问题,请参考以下文章