笔记就 懒得搞得有多好看了 自己看的顺就行
贴个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
UVA12558 埃及分数 Egyptian Fractions (HARD version) 笔记
原文:https://www.cnblogs.com/Cattttttttt/p/11349594.html