Codevs 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/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 Description
a b
输出描述 Output Description
若干个数,自小到大排列,依次是单位分数的分母。
样例输入 Sample Input
19 45
样例输出 Sample Output
5 6 18
数据范围及提示 Data Size & Hint
分类标签 Tags
搜索

/*
经典迭代搜索问题.
打了将近俩小时orz. 
这题主要是剪枝(能保证正确性就剪剪剪233).
分数个数少的优,最大的分母小优.
先搞一个解答树的深度.
然后从小枚举分母.
剪枝的话.
(1) t=max(t,get_m(x,y))//当前最小分母,
第一次没加T了,原来是有个地方没return 不加也能过但要特判2333.
(2) if((maxd-d+1)*y<=x*i) return 可行性剪枝(这题就靠它了原理so easy).
(3) 剪掉不合法的最后一层 可以降常数.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 101
#define LL long long
using namespace std;
int tot,a,b,maxd=1;
LL ans[MAXN],s[MAXN];
bool flag;
bool check(int x)
{
    if(ans[maxd]>s[maxd]) return true;
    for(int i=1;i<=x;i++)
      if(ans[i]==ans[0]) return true;
    return false;
}
int get_m(LL x,LL y)
{
    tot=1;
    while(x*tot<y) tot++;
    return tot-1;
}
int gcd(LL x,LL y)
{
    if(!y) return x;
    return gcd(y,x%y);
}
void dfs(LL x,LL y,int d,int t)
{
    if(d==maxd){
        if(x!=1) return ;
        s[maxd]=y;
        if(check(maxd))
        {
            for(int i=1;i<=maxd;i++) ans[i]=s[i];
            flag=true;
            return ;
        }
        return ;
    }
    t=max(t,get_m(x,y));
    for(int i=t+1;;i++)
    {
        if((maxd-d+1)*y<=x*i) return ;
        LL xx=x*i-y,yy=y*i;s[d]=i;
        int g=gcd(xx,yy);xx/=g,yy/=g;
        if(d+1==maxd&&xx!=1) continue;
        dfs(xx,yy,d+1,i);
    }
    return ;
}
int main()
{
    memset(ans,127/3,sizeof ans);
    scanf("%d %d",&a,&b);
    for(;;maxd++)
    {
        dfs(a,b,1,get_m(a,b));
        if(flag) break;
    }
    for(int i=1;i<=maxd;i++) printf("%d ",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/nancheng58/p/10068166.html