在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。
如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。
对于一个分数a/b,表示方法有很多种,但是哪种最好呢?
首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。
如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。 给出a,b(0〈a〈b〈1000),编程计算最好的表达方式。
以下为我参考的代码和理解:
// 按照分母递增的顺序来扩展,若扩展到d层时,前d个分数之和为 now ,而第d个分数为 1 / maxdion,则接下来
//至少还要( frac - now ) / (1 / maxdion)个分数,和才能“达到”frac(假设后面每个分母都为maxdion,即分数最大).
#include<iostream> using namespace std; double frac; // a /b int depth=1; const double error=1e-7; //精度,假设满足此精度,所得分数相加等于frac double dabs(double x) { return x > 0 ? x : -x; } bool dfs(int d,double now,int dion) { if(d == depth) //出口 { if(dabs(frac - now) < error) return true; return false; //剪枝 } int maxdion= (int)((depth-d) / ( frac - now )); //maxdion为当前可以存在的最大分母 for(;dion <= maxdion; ++dion) { if( dfs(d+1 , now + 1.0 / dion , dion+1)) { printf("1 /%d ", dion); return true; } } return false; } int main() { int a,b; scanf("%d%d",&a,&b); frac=(double)a / b; while(dfs(0,0.0, (int)(1.0 / frac )+1)== false) //此处若1/(x-1) >a / b >1/x 则 dion从x开始,若a / b = 1 / x, //则从x+1开始 最后推出 1/(frac) +1就可推出此数。 { ++depth; }printf("\n"); system("pause"); return 0; }
迭代加深搜索 埃及分数
最新推荐文章于 2023-08-19 21:16:22 发布