1288 埃及分数

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

在古埃及,人们使用单位分数的和(形如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),编程计算最好的表达方式。

输入描述 Input Description

a b

输出描述 Output Description

若干个数,自小到大排列,依次是单位分数的分母。

样例输入 Sample Input

19 45

样例输出 Sample Output

5 6 18

/*
经典基础IDA*
搜索无指定界限所以手动规定。因为要求分母尽量小,所以先找最小分母做下界
然后规定层数迭代搜 ans存分母
因为从小到大依次搜,层数加深,第一次找到的一定最优。
估价函数:若扩展到i层时,前i个分数之和为c/d,第i个分数为1/e
因为分母递增,所以接下来至少还需要>(a/b-c/d)/(1/e)个分数,总和才能到a/b.
此估价函数可以估计出最少多少步可以到达解,也就是说限定了层数。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> #define N 10001
#define ll long long using namespace std; int minn;
ll a,b,deep;
ll ans[N],v[N]; inline ll read()
{
ll x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline ll gcd(ll x,ll y)
{
if(x<y) x^=y,y^=x,x^=y;
int tmp;
while(y){
tmp=x%y;x=y;y=tmp;
}return x;
} inline bool better(int d)
{
for(int i=d;i>=;i--)
return ans[i]==- || v[i]<ans[i];
return false;
} inline int get(ll x,ll y)//当前下界
{
for(int i=;;++i) if(y<x*i) return i;
} bool IDA(int d,int minn,ll aa,ll bb)
{
if(d==deep)
{
if(bb%aa) return false;//分子必须是1.因为已经约分,不必但心aa不为1
v[d]=bb/aa;
if(better(d)) memcpy(ans,v,sizeof(ll)*(d+));
return true;
}
bool flag=false;
minn=std::max(minn,get(aa,bb));//也算剪枝,minn在不断增大
for(int i=minn;;++i)
{
if(bb*(deep-d+)<=i*aa) break;
//估价函数:因为i在增大,所以如果剩下的deep-d+1个分数全部都是1/i,加起来仍然不超过aa/bb,则无解,需要阔搜索层数
v[d]=i;
ll b2=bb*i,a2=aa*i-bb;//计算aa/bb-1/i
ll g=gcd(a2,b2);
if(IDA(d+,minn+,a2/g,b2/g)) flag=true;
}
return flag;
} int main()
{
a=read();b=read();
minn=get(a,b);
for(deep=;;deep++)
{
memset(ans,-,sizeof ans);//don't forget
if(IDA(,get(a,b),a,b))//get 得到搜索下界
break;
}
for(int i=;i<=deep;++i) printf("%d ",ans[i]);
return ;
}

codevs1288 埃及分数(IDA*)的更多相关文章

  1. CodeVS1288埃及分数(IDA*)

    在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法有很多种,但 ...

  2. 埃及分数-IDA*

    Description 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的.对于一个分数a/b, ...

  3. codevs1288 埃及分数

    题目描述: 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法 ...

  4. 埃及分数&&The Rotation Game&&骑士精神——IDA*

    IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...

  5. 埃及分数问题(带乐观估计函数的迭代加深搜索算法-IDA*)

    #10022. 「一本通 1.3 练习 1」埃及分数 [题目描述] 在古埃及,人们使用单位分数的和(形如 $\dfrac{1}{a}​$​​ 的,$a$ 是自然数)表示一切有理数.如:$\dfrac{ ...

  6. 华为OJ平台——将真分数分解为埃及分数

    题目描述: 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数.如:8/11 = 1/2+1/5+1/55+1/110. 输入: 输入一个真分数, ...

  7. UVA12558 Egyptian Fractions (HARD version)(埃及分数)

    传送门 题目大意 给出一个真分数 a/b,要求出几个互不相同的埃及分数(从大到小),使得它们之和为 a/b (埃及分数意思是分子为1的分数,详见百度百科) 如果有多组解,则分数数量少的优先 如果分数数 ...

  8. 埃及分数问题_迭代加深搜索_C++

    一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19 ...

  9. Vijos 1308 埃及分数(迭代加深搜索)

    题意: 输入a.b, 求a/b 可以由多少个埃及分数组成. 埃及分数是形如1/a , a是自然数的分数. 如2/3 = 1/2 + 1/6, 但埃及分数中不允许有相同的 ,如不可以2/3 = 1/3 ...

随机推荐

  1. atom 插件安装【转载】

    http://www.cnblogs.com/20145221GQ/p/5334762.html 问题: 输入apm install后,可能一直没有响应,要强行退. 不知道安装的时候可不可以打开ato ...

  2. Mock随机生成数据模拟后台接口

    <html> <head> <title>测试</title> <script src="http://code.jquery.com/ ...

  3. 谷歌浏览器中a:link设置字体颜色无效问题

    <div id="box"> <a href="#">111111</a> <a href=""& ...

  4. 零基础学习Linux培训,应该选择哪个培训班?

    云计算早已不是什么稀奇的概念,它的火爆让Linux运维工程师这个职业越来越重要.在当今各类云平台提供的系统中,Linux系统几乎毫无争议的独占鳌头,市场份额进一步扩张. 这也让Linux运维工程师职位 ...

  5. 洛谷——P1613 跑路

    P1613 跑路 题目大意: 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零.可是小A偏偏又有赖床的坏毛病.于是为了保住自己的工资,小A买了一个十分牛B ...

  6. Codeforces Round #467 Div.2题解

    A. Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  7. C++ 中 字符数组 和 指针 区别

    char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; c ...

  8. ubuntu18.04安装chrome浏览器

    前几天把系统弄崩溃了,弄了好久也没弄好,索性直接装18.04,下面是安装chrom浏览器的步骤,网络上照着16.04安装的,应该是一样的 启动终端. 输入以下命令: sudo wget http:// ...

  9. C库的制作

    1.库的概念:库是一种可执行的二进制形式: 2.分类: 1>静态库 ①.在程序编译时会被连接到目标代码中: ②.程序运行时不再需要该静态库: ③.体积较大: 2>动态库/共享库 ①.在程序 ...

  10. textarea 提交到数据库的内容,输出到 html 中显示正常的格式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...