埃及分数问题(迭代加深)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 LL tmpans[100000],ans[100000];
 5 int maxd;
 6 /**
 7  *学习:1.memcpy:复制结构体时加&,
 8              数组时不加,数组名即地址
 9         2.迭代加深搜索,剪枝条
10  * */
11 int get_maxb(LL a,LL b){
12     //
13     //for(int i = 1 ; ; i ++){
14     //    if(a*i >= b) return i;
15     //}
16     return b/a+1;
17 }
18 bool is_better(int d){
19     for(int i = d ; i >= 0 ; i --) if(tmpans[i] != ans[i]){
20         return ans[i] == -1 || tmpans[i] < ans[i];
21     }
22     return false;
23 }
24
25 bool dfs(int d,int from,LL a,LL b){
26     if(d == maxd){
27         if(b%a) return false;
28         tmpans[d] = b / a;
29         if(is_better(d)) memcpy(ans,tmpans,sizeof(LL) * (d+1));
30         return true;
31     }
32     //
33     bool ok = false;
34     from = max(from,get_maxb(a,b));
35     for(int i = from ; ; i ++){
36         // 剪枝
37         if(a*i >= (maxd-d+1) * b) break;
38         tmpans[d] = i;
39         // 剩下的分数
40         LL bb = b*i;
41         LL aa = a*i - b;
42         LL g = __gcd(aa,bb);
43         if(dfs(d+1,i+1,aa/g,bb/g)) ok = true;
44     }
45     return ok;
46 }
47
48 int main(){
49     LL a,b;
50     int kase = 1;
51     while(scanf("%lld%lld",&a,&b) != EOF && (a || b)){
52         bool ok = false;
53         memset(ans,-1,sizeof(ans));
54         for(maxd = 1 ; ; maxd ++){
55             if(dfs(0,get_maxb(a,b),a,b)) { ok = true; break; }
56         }
57         printf("Case %d:%lld/%lld=",kase++,a,b);
58         for(int i = 0 ; i < maxd ; i ++) printf("%d/%lld+",1,ans[i]);
59         printf("%d/%lld\n",1,ans[maxd]);
60     }
61     return 0;
62 }
时间: 2024-11-08 23:54:47

埃及分数问题(迭代加深)的相关文章

vijos1308 埃及分数(迭代加深搜索)

题目链接:点击打开链接 题目描述: 在古埃及,人们使用单位分数的和(形如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

埃及分数,迭代加深

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

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

埃及分数(迭代深搜)

#include<bits/stdc++.h> using namespace std; long long ch,mo; int dep; long long ans[1000],s[1000]; int gcd(long long a,long long b) { return b==0?a:gcd(b,a%b); } void outp() { if(ans[dep]>s[dep]) { for(int i=1;i<=dep;i++) ans[i]=s[i]; } } voi

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

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

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

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

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

迭代加深搜索(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

DFSID:埃及分数

题目描述  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