Vijos 1308 埃及分数(迭代加深搜索)
题意:
输入a、b, 求a/b 可以由多少个埃及分数组成。
埃及分数是形如1/a , a是自然数的分数。
如2/3 = 1/2 + 1/6, 但埃及分数中不允许有相同的 ,如不可以2/3 = 1/3 + 1/3.
求出可以表达a/b个数最少埃及分数方案, 如果个数相同则选取最小的分数最大。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int maxd;
long long v[],ans[];
bool better(int d){
for(int i = d; i >= ; i--){
if(v[i] != ans[i]){ //如果这一层没有标记, 或者标记的数小于传入的v[i], 说明当前为更优解
return ans[i] == - || v[i] < ans[i];
}
return false;
}
}
//求满足 1/c <= a/b 最大的1/c, 即最小的c
inline int get_first(LL a,LL b){
return b/a+;
}
//当前深度为d, 分母不能小于from, 分数之和为aa, bb
bool dfs(int d, int from, LL aa, LL bb){ if( d == maxd){
if(bb % aa) return false;
v[d] = bb / aa;
if(better(d)) memcpy(ans, v , sizeof(v));
return true;
} bool ok = false;
from = max(from, get_first(aa, bb)); // 如果上一次递归的from不符合aa/bb最小的分母, 则取get_first(aa,bb) for(int i = from; ; i++) {
// 剪枝:如果剩下的maxd+1-d个分数全部都是1/i,加起来仍然不超过aa/bb,则无解
if(bb * (maxd+-d) <= i * aa) break;
v[d] = i;
// 计算aa/bb - 1/i,设结果为a2/b2
LL b2 = bb*i;
LL a2 = aa*i - bb;
LL g = __gcd(a2, b2); // 以便约分
if(dfs(d+, i+, a2/g, b2/g)) ok = true;
}
return ok;
}
int main(){
int a, b;
scanf("%d %d", &a, &b);
for(maxd = ; ;maxd++){ //这里可以做一些限制, 层数上限不一定为infinite
memset(ans, -, sizeof(ans));
if(dfs(,get_first(a,b),a,b)) {
break;
}
}
for(int i = ; i <= maxd; i++) printf("%lld ", ans[i]);
}
Vijos 1308 埃及分数(迭代加深搜索)的更多相关文章
- Vijos 1308 埃及分数 - 迭代加深
描述 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的.对于一个分数a/b,表示方法有很多种, ...
- 埃及分数 迭代加深搜索 IDA*
迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...
- codevs 1288 埃及分数 (迭代加深搜索)
题目大意:给你一个分数$a/b$,把它拆解成$\sum_{i=1}^{n}1/ai$的形式,必须保证$ai$互不相同的情况下,尽量保证n最小,其次保证分母最大的分数的分母最小 什么鬼玄学题!!! 因为 ...
- 埃及分数问题_迭代加深搜索_C++
一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19 ...
- vijos1308 埃及分数(迭代加深搜索)
题目链接:点击打开链接 题目描写叙述: 在古埃及.人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不同意2/3=1/3+1/3,由于加数中有同样的.对于 ...
- UVA12558 Egyptian Fractions (HARD version) (埃及分数,迭代加深搜索)
UVA12558 Egyptian Fractions (HARD version) 题解 迭代加深搜索,适用于无上界的搜索.每次在一个限定范围中搜索,如果无解再进一步扩大查找范围. 本题中没有分数个 ...
- [Vijos1308]埃及分数(迭代加深搜索 + 剪枝)
传送门 迭代加深搜索是必须的,先枚举加数个数 然后搜索分母 这里有一个强大的剪枝,就是确定分母的范围 #include <cstdio> #include <cstring> ...
- POJ1129Channel Allocation[迭代加深搜索 四色定理]
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14601 Accepted: 74 ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
随机推荐
- OpenCV认识之发展历史
OpenCV认识之发展历史刚接触OpenCV,据说是专门用于机器视觉,机器人图形图像处理等,但对OpenCV的历史还不是特别了解,今天上网查好多资料,记录在此,OpenCV的全称是:Open Sour ...
- C++ multiset通过greater、less指定排序方式,实现最大堆、最小堆功能
STL中的set和multiset基于红黑树实现,默认排序为从小到大. 定义三个multiset实例,进行测试: multiset<int, greater<int>> gre ...
- 多线程 synchronized锁定当前对象
synchronized(this) 和synchronized一样,都是锁定当前对象. public class Task { synchronized public void otherMetho ...
- UltraEdit配置C++开发环境
1.下载UltraEdit软件安装 2.下载MinGW库安装 3.在系统设置环境变量,在path里加上你的MinGW\bin目录即可. 4.进入UltraEdit软件进行如下配置: 菜单栏---高级- ...
- 贪心 Codeforces Round #304 (Div. 2) B. Soldier and Badges
题目传送门 /* 题意:问最少增加多少值使变成递增序列 贪心:排序后,每一个值改为前一个值+1,有可能a[i-1] = a[i] + 1,所以要 >= */ #include <cstdi ...
- AIX系统常用命令
netstat -an | grep 9090 可以看到该端口正被监听,但却不知道是哪个进程占用了该端口 1. netstat -Aan|grep 端口号找到该端口连接对应的PCB/ADDR和连接的 ...
- iOS开发隐藏tabBar的问题
开发中遇到第一个页面需要显示tabBar,但是第二个页面不需要显示,当回到第一个页面的时候又需要显示的情况. 在第一个页面跳转到第二个页面的时候需要给第二个页面设置tabBar的隐藏 - (void) ...
- Selenium中验证码处理
验证码的主要实现方法 1.读取方式:在服务器目录下保存制作好的图片文件.然后在web页面上让用户识别,这种方式完全可以通过URL来破解图片的地址,通过图片地址可以间接的知道图片表示的验证码是什么所以这 ...
- 【C#】枚举
枚举 public static class CommonEnums { public enum people { /// <summary> ///男人 /// </summary ...
- sass 常用用法笔记
最近公司开发的h5项目,需要用到sass,所以领导推荐让我去阮一峰大神的SASS用法指南博客学习,为方便以后自己使用,所以在此记录. 一.代码的重用 1.继承:SASS允许一个选择器,继承另一个选择器 ...