题目地址:

https://www.acwing.com/problem/content/1122/

在古埃及,人们使用单位分数的和(形如1a\frac{1}{a}a1​的,aaa是自然数)表示一切有理数。如:23=12+16\frac{2}{3}=\frac{1}{2}+\frac{1}{6}32​=21​+61​,但不允许 23=13+13\frac{2}{3}=\frac{1}{3}+\frac{1}{3}32​=31​+31​,因为加数中有相同的。对于一个分数ab\frac{a}{b}ba​,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。如:1945=13+112+11801945=13+115+1451945=13+118+1301945=14+16+11801945=15+16+118\frac{19}{45}=\frac{1}{3}+\frac{1}{12}+\frac{1}{180}\\ \frac{19}{45}=\frac{1}{3}+\frac{1}{15}+\frac{1}{45}\\ \frac{19}{45}=\frac{1}{3}+\frac{1}{18}+\frac{1}{30}\\ \frac{19}{45}=\frac{1}{4}+\frac{1}{6}+\frac{1}{180}\\ \frac{19}{45}=\frac{1}{5}+\frac{1}{6}+\frac{1}{18}4519​=31​+121​+1801​4519​=31​+151​+451​4519​=31​+181​+301​4519​=41​+61​+1801​4519​=51​+61​+181​最好的是最后一种,因为 118\frac{1}{18}181​比1180\frac{1}{180}1801​,145\frac{1}{45}451​,130\frac{1}{30}301​,1180\frac{1}{180}1801​都大。注意,可能有多个最优解。如:59211=14+136+1633+1379859211=16+19+1633+13798\frac{59}{211}=\frac{1}{4}+\frac{1}{36}+\frac{1}{633}+\frac{1}{3798}\\ \frac{59}{211}=\frac{1}{6}+\frac{1}{9}+\frac{1}{633}+\frac{1}{3798}21159​=41​+361​+6331​+37981​21159​=61​+91​+6331​+37981​由于方法一与方法二中,最小的分数相同,因此二者均是最优解。给出a,ba,ba,b,编程计算最好的表达方式。保证最优解满足:最小的分数≥1107≥\frac{1}{10^7}≥1071​。

输入格式:
一行两个整数,分别为aaa和bbb的值。

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

数据范围:
0<a<b<10000<a<b<10000<a<b<1000

思路是迭代加深。其实就是直接枚举每个单位分数的分母,找到最优答案即可。在分解ab\frac{a}{b}ba​的时候,如果不限制深度,容易走到非常深的位置还不一定能找到最优解,所以最好的办法还是迭代加深。对于DFS每一层,设当前深度是ddd,就枚举第ddd个数的分母可以取哪些数。我们可以逐层按照分母从小到大枚举,这样第ddd个数的分母首先要严格大于上一层枚举的分母。其次,设当前层还需要凑出的分数是ab\frac{a}{b}ba​,先对其约分,如果a=1a=1a=1了,那么就找到了一个解,查看其是否更优(即其最大分母是不是小于之前找到的解的最大分母),如果更优则覆盖之前的解(当然如果之前没找到解,那么当前解直接覆盖);否则开始枚举一个分数,设当前枚举的数是1x\frac{1}{x}x1​,首先有1x<ab\frac{1}{x}<\frac{a}{b}x1​<ba​,所以有x>bax>\frac{b}{a}x>ab​,由于a≠1a\ne 1a​=1,所以其等价于x≥⌊ba⌋+1x\ge \lfloor \frac{b}{a}\rfloor + 1x≥⌊ab​⌋+1;此外,由于是按照分母从小到大枚举的,设当前DFS设定的最大深度是DDD,那么还需要枚举D−d+1D-d+1D−d+1个数(包括本层枚举的数),所以有(D−d+1)1x>ab(D-d+1)\frac{1}{x}>\frac{a}{b}(D−d+1)x1​>ba​,即x≤⌊ba(D−d+1)⌋x\le\lfloor\frac{b}{a}(D-d+1)\rfloorx≤⌊ab​(D−d+1)⌋。所以只需枚举这个范围内的数即可。代码如下:

#include <iostream>
#include <cstring>
using namespace std;const int N = 1e7;
int res[N], tmp[N];// 求a和b的最大公约数,用于约分
long gcd(long a, long b) {return b ? gcd(b, a % b) : a;
}// u表示本层应该从哪里开始枚举分母
bool dfs(int u, long a, long b, int depth, int max_depth) {if (depth == max_depth) {if (a == 1) {// 如果分母大于了10^7,则与题目给出的数据范围不符,直接返回falseif (b > 1e7) return false;tmp[depth - 1] = (int) b;// 如果是第一次算出解,或者已经算出的解不够最优,则更新答案if (!res[0] || b < res[depth - 1]) {memcpy(res, tmp, depth * (sizeof(int)));}return true;}return false;}bool found = false;// 枚举当前层的分数的分母for (int i = max(u, (int) (b / a) + 1); i <= b / a * (max_depth - depth + 1); i++) {// 用long以防溢出long nx = a * i - b, ny = b * i;// 做约分long g = gcd(nx, ny);nx /= g, ny /= g;// 存储一下当前选择tmp[depth - 1] = i;// 当前选的分母是i,下一层至少要从i + 1开始枚举分母if (dfs(i + 1, nx, ny, depth + 1, max_depth)) found = true;}return found;
}int main() {int a, b;scanf("%d%d", &a, &b);int g = (int) gcd(a, b);a /= g, b /= g;int max_depth = 1;while (!dfs(2, a, b, 1, max_depth))max_depth++;for (int i = 0; i < max_depth; i++)printf("%d ", res[i]);printf("\n");return 0;
}

时间复杂度指数级,空间取决于具体输入的搜索深度。

【ACWing】1120. 埃及分数相关推荐

  1. 埃及分数 ← IDA*

    [题目来源] https://www.luogu.com.cn/problem/P1763 https://www.acwing.com/problem/content/description/112 ...

  2. 2013年第四届蓝桥杯C/C++ A组国赛 —— 第三题:埃及分数

    标题:埃及分数 古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解.古埃及喜欢把一个分数分解为类似: 1/a + 1/b 的格式. 这里,a 和 b 必须是不同的两个整数,分子必须为 1 比如 ...

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

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

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

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

  5. 华为机试HJ82:将真分数分解为埃及分数

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将 ...

  6. 埃及分数怎么计算java_贪心算法之埃及分数问题(附c++源代码)

    感谢博主提供算法思路http://blog.csdn.net/tterminator/article/details/50927393 博主的是java代码,在这里写个c++代码,只是牛客网中有些很无 ...

  7. 埃及分数问题+迭代加深搜索

    理论上可以用回溯法求解,但是解答树非常恐怖,其一深度没有明显上限,1/i的值似乎可以在枚举不断更大的i时越来越小:其二加数的选择在理论上无限制. 解决方案采用迭代加深搜索:从小到大枚举深度上限maxd ...

  8. python埃及分数_送你一份低折扣书单,Python就占了6本,人工智能2本

    小编没什么好礼物送给大家的,这里有几本超低折扣的几本书,分享给你,为您省点小钱,不谢哟!此书单中,Python书有6本,少儿编程书4本,人工智能书2本.哪一本是你的菜,自己选吧! 文中这几本书折扣价在 ...

  9. 埃及分数拆分——IDA*

    埃及分数问题 题意 分析 思路 参考 代码 题意 在古埃及,人们使用单位分数的和(即1/a,a是自然数)表示一切有理  数. 例如,2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为在加数中 ...

最新文章

  1. python twisted教程_Python Twisted系列教程16:Twisted 进程守护
  2. 2020中国高校毕业生薪资排行出炉!原来有这么多双非院校薪资这么高!
  3. html中for标记,C#使用for循环移除HTML标记
  4. Java中普通字符串转json_java普通对象和json字符串的互转
  5. Material Design(十一)--CoordinatorLayout和自定义视图
  6. 线程的CloseHandle和WaitForSingleObject
  7. SVM熟练到精通5:MATLAB实例
  8. 百度兴趣点下载工具设计和实现
  9. CRM one order性能调优指南
  10. 内网击穿之 HTTP 穿透:网站没上线?如何让全世界的人都可以访问你本地的网站?
  11. redmine一键安装
  12. 若依框架前端问题总结
  13. final、finally、finalize
  14. winform公共标签和常用属性
  15. 万字长文 | 线性代数的本质课程笔记完整合集!
  16. [复变函数]第20堂课 5.4 整函数与亚纯函数的概念
  17. ubuntu win10 双系统 卸载ubuntu
  18. 如何安装百度分享按钮
  19. ZBrush笔刷属性栏简介
  20. 腾讯云产品文档----负载均衡

热门文章

  1. 华为机试真题实战应用【赛题代码篇】-磁盘容量排序(附Python、Java和C++代码)
  2. 博客搬家 -- 将博客从CSDN迁移到hexo上
  3. 微信小程序关闭按钮样式设计
  4. 计算机硬件五部分关系,计算机内部的五大组件是什么?,计算机五大部件的关系图...
  5. android+7.0+nexus,Nexus新机搭安卓7.0+4G全网通
  6. 企业CDN缓存加速原理解密
  7. NAT(网络地址转换)小实验
  8. springboot获取文件路径
  9. ctfshow web
  10. java-net-php-python-39jspm垃圾回收管理系统计算机毕业设计程序