什么是迭代加深搜索:
对于深度d比较大的情况,深度优先搜索需要很长的运行时间,而且还可能得不到解答。一种比较好的问题求解方法是对搜索树的深度进行控制,即有界深度优先搜索方法。有界深度优先搜索过程总体上按深度优先搜索方法进行,但对搜索深度需要给出一个深度限制dm,当深度达到了dm的时候,如果还没有找到解答,就停止对该分支的搜索,换到另外一个分支进行搜索。
迭代指的是当在一个深度范围内找不到解时,扩大深度范围。
埃及分数:
在古埃及,人们使用单位分数的和(如1/a,a是自然数)表示一切有理数。例如,2/3 = 1/2 + 1/6,但不允许 2/3 = 1/3 + 1/3,因为在加数中不允许有相同的。
对于一个分数 a/b ,表示方法有很多种,其中加数少的比加数多的好,如果加数个数相同,则最小的分数越大越好。例如, 19 / 45 = 1 / 5 + 1/ 6 + 1 / 18 是最优方案。
输入整数 a,b(0 < a < b < 1000),试编程计算最佳表达式。
#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; //剪枝
}
//maxdion为当前可以存在的最大分母
/*
depth - d:剩下还有多少个数
frac - now:剩下的数
(frac - now)/(depth - d):表示剩下的每个数至少多大,
反过来就表示当前可以存在的最大分母
*/
int maxdion= (int)((depth-d) / ( frac - now ));
/*
* 用到了回溯算法
*/
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)
++depth;
printf("\n");
return 0;
}