• [题解]「一本通 1.3 练习 1」埃及分数


    埃及分数题目链接

    这道题比较经典。

    算法:迭代加深+IDA*

    优化:

    1.迭代加深

    2.确定从小到大的搜索顺序

    3.确定搜索上下界

    (1)以i为分母的数字不能大于a/b.

    (2)如果后面的数字都以i为分母仍然<=a/b,退出。

    细节:

    (1)在通分过程中会爆int。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll unsigned long long 
    #define R register
    using namespace std;
    const int N=1e5+5;
    ll ans_a,ans_b,ans[N],lin[N],k,flag,vis[N];
    inline ll gcd(R ll a,R ll b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
    inline void dfs(R ll x,R ll a,R ll b,ll lst)//正在填第几个   
    {
        if(x==k){
            if(b%a==0)
            {
                flag=1;
                ans[k]=b/a;
                if(ans[k]<lin[k])
                for(R ll i=1;i<=k;i++)
                lin[i]=ans[i];
            }
            return;
        }
        for(R ll i=lst+1;i;i++)
        {
            if((k-x+1)*b<=a*i)break;
            if(i*a<b)continue;
            R ll zi=i*a-b;
            R ll mu=i*b;
            R ll g=gcd(zi,mu);
            ans[x]=i;
            dfs(x+1,zi/g,mu/g,i);
            ans[x]=0;
        }
    }
    int main(){
        scanf("%lld%lld",&ans_a,&ans_b);cn
        k=0;
          k=gcd(ans_a,ans_b);
          ans_a/=k;   ans_b/=k;
          k=0;
          memset(lin,127,sizeof(lin));
          while(!flag)
          {
              k++;
              dfs(1,ans_a,ans_b,0);
          }
          for(R ll i=1;i<=k;i++)
          printf("%lld ",lin[i]);
          return 0;
    }
    //迭代加深
    //上下界剪枝
  • 相关阅读:
    二分搜素——(lower_bound and upper_bound)
    二分(搜索)查找
    算法复杂度中的O(logN)底数是多少
    hdu 1050 Moving Tables
    hdu 1010 Tempter of the Bone
    hud 3123 GCC
    “123”——> 123
    基本模运算
    101个MySQL的调节和优化的Tips
    一个最简单的图片缩略图
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9898345.html
Copyright © 2020-2023  润新知