迭代加深搜索 埃及分数

      在古埃及,人们使用单位分数的和(形如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;
}


你可能感兴趣的:(编程,System,扩展)