【习题 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 several sample(at least therr) yourself?
    3.Can you promise that the solution is right? At least,the main ideal
    4.use the puts("") or putchar() or printf and such things?
    5.init the used array or any value?
    6.use error MAX_VALUE?
    7.use scanf instead of cin/cout?
    8.whatch out the detail input require
*/
/*
    一定在这里写完思路再敲代码!!!
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e3;

bool bo[N+10];
int a,b,k,maxdep;
vector<ll> v,ans;

ll getidx(int a,int b){
    //1/i <= a/b 且 i最小
    //b<=a*i
    ll l= 1,r = 1e8;
    ll temp = -1;
    while (l <= r){
        int m = (l+r)>>1;
        if (1LL*a*m>=b){
            temp = m;
            r = m - 1;
        }else l = m + 1;
    }
    return temp;
}

bool Greater(vector<ll> v,vector <ll> ans){
    if ((int)ans.size()==0) return true;
    for (int i = (int)v.size()-1;i>=0;i--)
        if (v[i]!=ans[i]){
                if (v[i]>ans[i]) return false;else return true;
            }
    return false;
}

bool dfs(int dep,int a,int b,ll last){
    if (dep==maxdep){
        if (a==1 && b>last){
            if (b<=1000 && bo[b]) return false;
            v.push_back(b);
            if (Greater(v,ans)) ans = v;
            v.pop_back();
            return true;
        }
        return false;
    }
    ll idx = getidx(a,b);
    ll ma = max(last+1,idx);
    ll delta = maxdep-dep+1;
    //delta/ma<a/b
    bool ok = false;

    for (ll i = ma; ;i++)
        {
            if (i<=1000 && bo[i]) continue;
            if (delta*b<a*i) break;
            //a/b - 1/i
            v.push_back(i);
            ll fenzi = a*i-b,fenmu = b*i;
            ll temp = __gcd(fenzi,fenmu);
            fenzi/=temp,fenmu/=temp;
            if (dfs(dep+1,fenzi,fenmu,i)) ok = true;
            v.pop_back();
        }
    return ok;
}

int main(){
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    int T;
    cin >> T;
    int kase = 0;
    while(T--){
        memset(bo,0,sizeof bo);
        cin >> a >> b >> k;
        while (k--){
            int x;
            cin >> x;
            bo[x] = 1;
        }
        ans.clear();
        v.clear();
        for (maxdep = 1;;maxdep++){
            if (dfs(1,a,b,1)){
                cout <<"Case "<<++kase<<": "<<a<<"/"<<b<<"=1/"<<ans[0];
                for (int i = 1;i <(int) ans.size();i++)
                    cout << "+1/"<<ans[i];
                break;
            }
        }
        cout << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/AWCXV/p/8159189.html

时间: 2024-10-11 23:25:32

【习题 7-7 UVA-12558】Egyptian Fractions (HARD version)的相关文章

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-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)

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

UVa 880 - Cantor Fractions

题目:按照三角形的形状摆放正整数(从1开始),递归的不断在原来的三角形的斜边上添加一条新边: 现在个你一个数字在这个构造中的序号,输出它的行列值. 分析:数学.第k个三角形包含前k(k+1)/ 2个元素,每次从左上角向下移动,横纵坐标之和为k+1: 计算出比n小的满足k(k+1)/ 2的k值,然后利用n - k(k+1)/ 2计算出位置即可. 说明:要使用long long,否则会溢出. #include <algorithm> #include <iostream> #inclu

UVa 275 - Expanding Fractions

题目:给你一个分数的分子和分母,求出他的循环节. 分析:模拟.根据鸽巢原理,设分母为m则计算中最多有m中不同的余数,所以循环节小于m. 说明:每次记录余数*10在取新的余数即可. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace

【例题 7-3 UVA - 10976】Fractions Again?!

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] x>=y => \(\frac{1}{x}<=\frac{1}{y}\) => \(\frac{1}{x}=\frac{1}{k}-\frac{1}{y}\) 结合两个式子可以得到 y<=2*k 则枚举y,然后根据式子得到x,判断合法性就ok [代码] /* 1.Shoud it use long long ? 2.Have you ever test several sample(at least ther