UVA12558 埃及分数 Egyptian Fractions (HARD version) 笔记
时间:2019-08-14
本文章向大家介绍UVA12558 埃及分数 Egyptian Fractions (HARD version) 笔记,主要包括UVA12558 埃及分数 Egyptian Fractions (HARD version) 笔记使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
笔记就 懒得搞得有多好看了 自己看的顺就行
贴个luogu链接 uva比较慢 UVA12558 埃及分数 Egyptian Fractions (HARD version)
一开始看着紫书写的 就是添加了个约束条件 现在理解了之后搞一个
题目是搜索 考虑BFS 状态数太多 一次要向不知道数量个状态转移 不行
考虑DFS 解决了状态数过多的问题 但是深度太深了 也不行
所以就IDDFS解决 每次把a/b减去一个1/c 直到到达深度限制且最后减去的为埃及分数并且分母不受限
代码
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; using std::cin; using std::cout; using std::endl; std::map<ll, int>map; //利用map来判断能不能用 ll ans[105], tmp[105]; //存答案 ll gcd(ll a, ll b) {if(a < b) std::swap(a, b); return b == 0 ? a : gcd(b, a % b);} //不知道static_cast和(int)()有什么区别 不过看着很吊就是了 ll get_first(ll a, ll b) {return static_cast<int>(b / a) + 1;} //得到1/c <= a/b的c的最大值 由1/c <= a/b可推导出b <= a * c 进而推导出b / a <= c bool check(int dep) { //判断最优解 for(int i = dep; i >= 0; i--) if(ans[i] != tmp[i]) return ans[i] == -1 || ans[i] > tmp[i]; //要求的是分母最小 ans[i] == -1判断 return false; } void replace(int dep) {for(int i = 0; i <= dep; i++) ans[i] = tmp[i];} bool IDDFS(int dep_lim, int dep, ll up, ll down, ll min) { //dep_lim为深度限制 dep为当前深度 up为剩下的分子 down为剩下的分母 bool flag = false; //因为是最优解 而第一个搜到的不一定是最优解 所以不能够搜到直接return if(dep >= dep_lim) { //深度大于等于限制是就需要判断了 if(down % up) return false; //因为埃及分数的分子只能为1(然而那题题面没写)所以如果分子不是1就不是答案 tmp[dep] = down / up; //得到分母 存入答案 if(map.count(tmp[dep])) return false; //如果分母不能用就不是 if(check(dep)) replace(dep); //更新最优解 return true; } for(int i = std::max(min, get_first(up, down)); ; i++) { //因为最后得出的那个的分母是递增的 所以遍历下界的第一个条件为上次的分母,也就是min 另外一个条件为1/c <= a/b时c的最小值,因为如果1/c > a/b,那么就不会有结果 if(down * (dep_lim - dep + 1) <= up * i) break; //如果剩下几个全为1/i,加起来也不超过up/down就直接break,因为随着i的增大1/i只会越来越小,由(dep_lim - dep + 1) * (1 / i) < up / down可推导出 if(map.count(i)) continue; //如果i为受限的分母 就不能选 tmp[dep] = i; //存答案 ll b = i * down; //由up/down - 1/i = a/b可得出 up/down - 1/i = a/b --> (up * i)/(down * i) - down/(i * down) = a/b --> a = up * i - down, b = down * i ll a = up * i - down; ll g = gcd(a, b); //gcd if(IDDFS(dep_lim, dep + 1, a/g, b/g, i + 1)) flag = true; } return flag; } int main() { int t; scanf("%d", &t); int it = 1; while(t--) { int a, b, k; memset(ans, -1, sizeof(ans)); memset(tmp, -1, sizeof(tmp)); map.clear(); scanf("%d%d%d", &a, &b, &k); for(int i = 0; i < k; i++) { ll tmp; scanf("%lld", &tmp); map[tmp] = 1; } int dep = 0; while(1) { if(IDDFS(dep, 0, a, b, get_first(a, b))) break; dep++; } printf("Case %d: %d/%d=", it++, a, b); for(int i = 0; i < dep; i++) printf("1/%d+", ans[i]); printf("1/%d\n", ans[dep]); } system("pause");//上交oj时记得注释或删除 return 0; }
不知道cnblogs怎么用latex就没用 一些细节也都标出来了 反正也是给自己看
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; using std::cin; using std::cout; using std::endl; std::map<ll, int>map; ll ans[105], tmp[105]; ll gcd(ll a, ll b) {if(a < b) std::swap(a, b); return b == 0 ? a : gcd(b, a % b);} ll get_first(ll a, ll b) {return static_cast<int>(b / a) + 1;} bool check(int dep) { for(int i = dep; i >= 0; i--) if(ans[i] != tmp[i]) return ans[i] == -1 || ans[i] > tmp[i]; return false; } void replace(int dep) {for(int i = 0; i <= dep; i++) ans[i] = tmp[i];} bool IDDFS(int dep_lim, int dep, ll up, ll down, ll min) { bool flag = false; if(dep >= dep_lim) { if(down % up) return false; tmp[dep] = down / up; if(map.count(tmp[dep])) return false; if(check(dep)) replace(dep); return true; } for(int i = std::max(min, get_first(up, down)); ; i++) { if(down * (dep_lim - dep + 1) <= up * i) break; if(map.count(i)) continue; tmp[dep] = i; ll b = i * down; ll a = up * i - down; ll g = gcd(a, b); if(IDDFS(dep_lim, dep + 1, a, b, i + 1)) flag = true; } return flag; } int main() { int t; scanf("%d", &t); int it = 1; while(t--) { int a, b, k; memset(ans, -1, sizeof(ans)); memset(tmp, -1, sizeof(tmp)); map.clear(); scanf("%d%d%d", &a, &b, &k); for(int i = 0; i < k; i++) { ll tmp; scanf("%lld", &tmp); map[tmp] = 1; } int dep = 0; while(1) { if(IDDFS(dep, 0, a, b, get_first(a, b))) break; dep++; } printf("Case %d: %d/%d=", it++, a, b); for(int i = 0; i < dep; i++) printf("1/%d+", ans[i]); printf("1/%d\n", ans[dep]); } //system("pause");//上交oj时记得注释或删除 retu
原文地址:https://www.cnblogs.com/Cattttttttt/p/11349594.html
- 我的第六个网页制作:table标签
- POJ 1163 The Triangle【dp+杨辉三角加强版(递归)】
- UVA 11039-Building designing【贪心+绝对值排序】 UVA11039-Building designing
- UVA 11636-Hello World!(水题,猜结论) UVA11636-Hello World!
- 百度某SDK设计缺陷导致手机敏感信息泄露(IMEI号和地理位置信息等)
- HDU 1004 Let the Balloon Rise【STL<map>】
- UVA 10881 - Piotr's Ants【模拟+思维】
- DFS中的奇偶剪枝学习笔记
- POJ 3154 Graveyard【多解,数论,贪心】
- HDU 1010 Tempter of the Bone【DFS经典题+奇偶剪枝详解】
- Ethereum - 以太坊项目
- COGS 144. [USACO Dec07] 魅力手镯【01背包复习】
- SQL Server 使用全文索引进行页面搜索
- HDU 1003 Max Sum【动态规划求最大子序列和详解 】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法