您的位置:首页 > 其它

埃及分数 迭代加深搜索 IDS

2011-06-19 10:50 295 查看
这种算法适合深度无上限的情况,适合解空间大但是解的深度小的情况。
http://acm.fjnu.edu.cn/problem/1341
在古埃及,人们使用单位分数的和(形如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),编程计算最好的表达方式。

下面的代码给出了长度最小的一个解(非最优解)。

from: http://tieba.baidu.com/f?kz=999476826
#include<iostream>
using namespace std;
double frac;
int depth = 1;
inline double abs(double d)
{
return d > 0 ? d : -d;
}
const double ERROR = 1e-7;
bool ids(int d, double now, int dino)
{
if (d == depth)
{
if (abs(frac - now) < ERROR)
{
return true;
}
return false;
}
int maxdino = (int)((depth - d) / (frac - now));
cout << "depth : " << d << ", checking from " << dino << " to " << maxdino << endl;
for (; dino <= maxdino; ++dino)
{
if (ids(d + 1, now + 1.0 / dino, dino + 1))
{
cout << dino << ' ';
return true;
}
}
return false;
}
int main()
{
int a, b;
cin >> a >> b;
frac = (double)a / b;
while (!ids(0, 0.0, (int)(1.0 / frac) + 1))
{
++depth;
}
cout << endl;
return 0;
}


运行结果:

/home/a/j/nomad2:cat input |./a.out
30 18 3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: