UVA-12558 Egyptian Fractions (HARD version) (IDA* 或 迭代加深搜索)

题目大意:经典的埃及分数问题。

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
# define LL long long

int num[5],a,b,k;
LL ans[10000],v[10000];

LL gcd(LL a,LL b)
{
    return (b==0)?a:gcd(b,a%b);
}
int get_first(LL a,LL b)
{
    return b/a+1;
}
bool judge(int val)
{
    for(int i=0;i<k;++i)
        if(val==num[i])
            return false;
    return true;
}
bool better(int d)
{
    for(int i=d;i>=0;--i)
        if(ans[i]!=v[i])
            return ans[i]==-1||v[i]<ans[i];
    return false;
}
bool dfs(int cur,int maxd,int from,LL aa,LL bb)
{
    if(cur==maxd){
        if(bb%aa)
            return false;
        v[cur]=bb/aa;
        if(!judge(v[cur]))
            return false;
        if(better(cur)){
            for(int i=0;i<=cur;++i)
                ans[i]=v[i];
        }
        return true;
    }
    bool ok=false;
    from=max(from,get_first(aa,bb));
    for(int i=from;;++i){
        while(!judge(i))
            ++i;
        if(bb*(maxd-cur+1)<=i*aa)
            break;
        v[cur]=i;
        LL b2=bb*i;
        LL a2=aa*i-bb;
        LL g=gcd(a2,b2);
        if(dfs(cur+1,maxd,i+1,a2/g,b2/g))
            ok=true;
    }
    return ok;
}
void solve()
{
    for(int maxd=1;;++maxd){
        memset(ans,-1,sizeof(ans));
        if(dfs(0,maxd,get_first(a,b),a,b)){
            printf("%d/%d=",a,b);
            for(int i=0;i<=maxd;++i)
                printf("1/%lld%c",ans[i],(i==maxd)?‘\n‘:‘+‘);
            break;
        }
    }
}
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&a,&b,&k);
        for(int i=0;i<k;++i)
            scanf("%d",num+i);

        printf("Case %d: ",++cas);
        solve();
    }
    return 0;
}

  

时间: 2024-10-12 17:57:52

UVA-12558 Egyptian Fractions (HARD version) (IDA* 或 迭代加深搜索)的相关文章

UVA 12558 Egyptian Fractions (HARD version)

题意: 经典的埃及分数问题,即给出一个真分数,求出用个数最少的单位分数来表示这个分数.如果有多种方案,要让每个分数尽量的大,即分母尽量的小.会有K个禁止使用的单位分数. 分析:    IDA*算法.当按照分母递增的顺序排列时, 如果当前考虑的分数为1/e,剩下的maxd - d+1层都是1/e,但仍然到不了目标的a/b的时候,就剪枝. 代码: #include <iostream>#include <cstdio>#include <cstring>#include &

12558 - Egyptian Fractions (HARD version)(IDA*算法)

IDA*算法,迭代加深搜索和A*算法的结合 . 迭代加深搜索适用于那些没有明显深度上限的题目,将深度从小到大枚举,直到找到最优解 ,减小了深搜的盲目性 . A*算法需要一个乐观估价函数,在这个函数里寻找一个代价最小的点去搜索,所以时间复杂度都浪费在这个上面了 . 代码如下: #include<bits/stdc++.h> using namespace std; typedef long long ll; int T,kase=0; ll v[10000+10],ans[10000+10],a

12558 - Egyptian Fractions (HARD version)

#include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long LL; const int maxn=10010; int maxd,t,tt; set<LL> sk; LL ans[maxn],v[maxn]; LL gcd(LL a,LL b){ return b?gcd(b, a%b):a;

UVA12558 Egyptian Fractions (HARD version) (埃及分数)

UVA12558 Egyptian Fractions (HARD version) 题解 迭代加深搜索,适用于无上界的搜索.每次在一个限定范围中搜索,如果无解再进一步扩大查找范围. 本题中没有分数个数和分母的上限,只用爆搜绝对TLE.故只能用迭代加深搜索. #include<cstdio> #include<cstring> #include<set> using namespace std; typedef long long ll; int num,T,t,k;

uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索

迭代加深搜索 自己看的时候第一遍更本就看不懂..是很水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题并且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的见解, 真的是很有帮助,也许自己想要想很久才能想明白,还会很痛苦,稍微问一下别人的想法,点上一个方向,剩下的自己就能想得明白了. 迭代加深. 把answer(需要的步数或其他)在主函数里面从零往上递加,此之谓 "层数",亦可谓之"深度".用书上的话就是: 从小到大枚举深度

UVA 11212 Editing a Book [迭代加深搜索IDA*]

11212 Editing a Book You have n equal-length paragraphs numbered 1 to n. Now you want to arrange them in the order of 1, 2, . . . , n. With the help of a clipboard, you can easily do this: Ctrl-X (cut) and Ctrl-V (paste) several times. You cannot cut

UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]

解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: 3)采用广度优先搜索结点数越来越多,耗时过大: 经过简单计算,最长大概10次左右的变换就能出解,于是笔者就尝试采用IDA*,迭代加深搜索的好处是: 1)无需存储状态,节约时间和空间: 2)深度优先搜索查找的结点数少: 3)递归方便剪枝: 代码如下: 1 #include <iostream> 2

UVA12558-Efyptian Fractions(HARD version)(迭代加深搜索)

Problem UVA12558-Efyptian Fractions(HARD version) Accept:187  Submit:3183 Time Limit: 3000 mSec  Problem Description Given a fraction a/b, write it as a sum of different Egyptian fraction. For example, 2/3 = 1/2 + 1/6. Thereisonerestrictionthough: th

【习题 7-7 UVA-12558】Egyptian Fractions (HARD version)

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 迭代加深搜索. 枚举最大量maxdep 在dfs里面传剩余的要凑的分子.分母 以及上一次枚举的值是多少. 然后找到最小的k,满足1/k<=分子/分母 然后从max(k,last+1)开始枚举. ->剪枝就是剩余的全都用这个最大的分数.如果都不行就肯定不行了. 二分找这个k. 不能用的数字就直接跳过就行. [代码] /* 1.Shoud it use long long ? 2.Have you ever test severa