博客
关于我
【紫书】UVA12558 埃及分数 Egyptian Fractions (HARD version)
阅读量:550 次
发布时间:2019-03-09

本文共 2090 字,大约阅读时间需要 6 分钟。

题目提交点

解题思路

这个题目数据范围有点小, 我刚开始想的是用dfs, 可是遇到了一些问题, 不知道他什么时候结束,最优解有几项,新加入的埃及分数取什么值最好等等问题困惑着我。

顺着理一下思路,需要暴力做这题,但是不知道上限,非常符合迭代加深搜的算法规则,OK,开始分析细节。

①迭代加深搜,搜到了就结束,没搜到就继续搜, dfs层数代表着埃及分数的项数。

②dfs剪枝, 层数超过了,或者累加的答案已经超过所要的答案了,进行剪枝操作。

③对埃及分数取值问题:

a, b 分别为已经累加到的数分子与分母,A, B分别为所需要的分子与分母。
设1/c 为所加的埃及分数, 便有
1/c + a / b <= A / B ==> 1/c <= A/B - a/b = (Ab - aB)/Bb ==> c >= Bb/(Ab - aB)
再与上一个已经取的值做比较,取最大,那么这个数就是最小的c值。

不一定这个最小的值是最好的,所以得不断的尝试, 让这个值自加。

设no 为最小的c的取值,max_d 为此dfs最大能到的层数, d 为当前层数。
当这个新取的埃及分数小到无论怎么取都达不到的值时,结束此埃及分数的取值,即 a/b + (max_d - d) / no < A / B

代码

#include
#include
using namespace std;#define _for(i, a, b) for (int i = (a); i < (b); ++i)#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)typedef long long LL;int A, B;unordered_set
R;inline int readint(){ int x; scanf("%d", &x); return x;}LL gcd(LL a, LL b){ return b ? gcd(b, a % b) : a;}LL get_first(LL a, LL b, LL last){ return max((B * b) / (A * b - a * B), last + 1);}bool judge(const vector
& D, const vector
& ans){ if (ans.empty()) return true; for (int i = ans.size() - 1; ~i; --i) if (D[i] != ans[i]) return D[i] < ans[i]; return false;}void dfs(LL a, LL b, const int d, const int max_d, vector
& D, vector
& ans){ if (d > max_d) return; if (a * B > A * b) return; if (a == A && b == B) { if (judge(D, ans)) ans = D; return; } LL no = get_first(a, b, D.empty() ? 1LL : D.back()); while (true) { if (a * B * no + (max_d - d) * B * b < A * b * no) break; if (!R.count(no)) { LL na = a * no + b, nb = b * no, g = gcd(na, nb); D.push_back(no); dfs(na / g, nb / g, d + 1, max_d, D, ans); D.pop_back(); } no++; }}int main(){ #ifdef LOCAL freopen("data.in", "r", stdin);#endif int T = readint(); _rep(kase, 1, T) { A = readint(), B = readint(); int k = readint(); R.clear(); _for(i, 0, k) R.insert(readint() * 1LL); for (int d = 2; ; ++d) { vector
D, ans; dfs(0, 1, 0, d, D, ans); if (!ans.empty()) { printf("Case %d: %d/%d=", kase, A, B); int sz = ans.size(); _for(i, 0, sz)printf("1/%lld%s", ans[i], (i == sz - 1) ? "\n" : "+"); break; } } } return 0;}

转载地址:http://qmzpz.baihongyu.com/

你可能感兴趣的文章
MySQLIntegrityConstraintViolationException异常处理
查看>>
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>
MySQL不同字符集及排序规则详解:业务场景下的最佳选
查看>>