[CODEVS 1288]埃及分数

Description

在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好。 如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。 给出a,b(0<a<b<1000),编程计算最好的表达方式。

Input

a b

Output

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

Sample Input

19 45

Sample Output

5 6 18

题解

迭代的入门经典题...然而我现在才做...

我们将深度迭代,搜索。

由于要使最小的分数最大,所以我们要边搜的时候记录当前状况下的最优解。

加个$A*$。

我们用估价函数算出枚举分母的范围区间。

注意开$int$会爆。

 1 #include<map>
 2 #include<ctime>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stack>
 6 #include<cstdio>
 7 #include<string>
 8 #include<vector>
 9 #include<cstring>
10 #include<cstdlib>
11 #include<iostream>
12 #include<algorithm>
13 #define LL long long
14 #define RE register
15 #define IL inline
16 using namespace std;
17 const LL INF=~0u>>1;
18
19 LL keep[100],ans[100];
20 LL gcd(LL a,LL b) {return b ? gcd(b,a%b):a;}
21
22 LL a,b,lim;
23
24 void Dfs(LL cen,LL x,LL y)
25 {
26     if (cen>lim) return;
27     LL g=gcd(x,y);x/=g;y/=g;
28     if (x==1&&y>keep[cen-1])
29     {
30         keep[cen]=y;
31         if (keep[cen]<ans[cen]) memcpy(ans,keep,sizeof(ans));
32         return;
33     }
34     LL s=y/x;
35     if (keep[cen-1]>=s) s=keep[cen-1]+1;
36     LL t=y*(lim-cen+1)/x;
37     for (LL i=s;i<=t;i++)
38     {
39         keep[cen]=i;
40         Dfs(cen+1,i*x-y,y*i);
41     }
42 }
43
44 int main()
45 {
46     scanf("%lld%lld",&a,&b);
47     for (;;lim++)
48     {
49         ans[lim]=INF;
50         Dfs(1,a,b);
51         if (ans[1]>0&&ans[1]<INF)
52         {
53             for (RE LL i=1;i<=lim;i++) printf("%lld ",ans[i]);
54             return 0;
55         }
56     }
57     return 0;
58 }
时间: 2024-11-09 02:16:06

[CODEVS 1288]埃及分数的相关文章

1288 埃及分数

1288 埃及分数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好. 如: 19/45=1/3 + 1/12 + 1/

埃及分数问题_迭代加深搜索_C++

一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19/45=1/3 + 1/12 + 1/180 二.迭代加深搜索 迭代加深搜索可以看做带深度限制的DFS. 首先设置一个搜索深度,然后进行DFS,当目前深度达到限制深度后验证当前方案的合理性,更新答案. 不断调整搜索深度,直到找到最优解. 三.埃及分数具体实现 我们用dep限制搜索层数,先从2开始,每

埃及分数,迭代加深

埃及分数题意非常明白,这里就不解释了…… 但是关于最优解的问题,题目并没有说明 原题: 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好. 然而这并没有考虑一种很恶心的情况:加数一样多,而且最后一个分数一样的时候,哪种情况最优呢? 我先写了个从末尾到开头一位一位判断大小,保证最大的程序,大概只有一半的分数(codevs) 又写了个输出 最先找到的 末尾最大的 方案 的程序,结果90(还是codevs) 我选择放弃,,,

【迭代加深搜索】埃及分数问题

谢谢阿苏~http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5856756 [迭代加深搜索(ID,iterative deepening)]:从小到大枚举上限maxd,每次执行只考虑深度不超过maxd的结点. ------对于可以用回溯法求解但解答树的深度没有明显上限的题目,可以考虑ID算法: ------优点:它主要是在递归搜索函数的开头判断当前搜索的深度是否大于预定义的最大搜索深度,如果大于,就退出这一层的搜索,如果不大于,就

将真数分解为埃及分数

问题: 输入一个分数,将该分数分解为埃及分数. 真分数:分子小于分母的分数 埃及分数:分子为一的分数 #include <stdio.h> #include <stdlib.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char *argv[]) { long in

将真分数分解为埃及分数

描述 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数.如:8/11 = 1/2+1/5+1/55+1/110. 接口说明 /* 功能: 将分数分解为埃及分数序列 输入参数:     String pcRealFraction:真分数(格式“8/11”) 返回值:     String pcEgpytFraction:分解后的埃及分数序列(格式“1/2+1/5+1/55+1/100”) */ public static String  Co

“埃及分数”问题浅谈对迭代加深搜索的理解

迭代加深搜索(IDDFS)的思想 迭代加深搜索一般用来求解状态树"非常深",甚至深度可能趋于无穷,但是"目标状态浅"的问题.如果用普通的DFS去求解,往往效率不够高.此时我们可以对DFS进行一些改进.最直观的一种办法是增加一个搜索的最大深度限制maxd,一般是从1开始.每次搜索都要在maxd深度之内进行,如果没有找到解,就继续增大maxd,直到成功找到解,然后break. 如下图所示,如果用DFS,需要15步才能找到结点3,但是用迭代加深搜索,很快即可找到结点3.

迭代加深,埃及分数

问题描述: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系列互不相同的单位分数(形如:1/a,即分子为1),要求:分解成的单位分数数量越少越好,如果数量一样,最小的那个单位分数越大越好. 如: 19/45 = 1/3 + 1/12 + 1/180; 19/45 = 1/5 + 1/6 + 1/18; 由于,1/18比1/180更大,所以第二种情况更优. 59/211=1/4 + 1/36 + 1/633 + 1/3798 59/211=1/6 + 1/9 + 1/633 + 1/37

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[1234],ans[1234