• 埃及分数


    迭代深搜 
    1.全场打long long
    2.搜索时,最小的数从大往小的搜
    其他的从小往大搜
    3.限制开头:并不是每次都要从1开始遍历分母,假设现在要分解a/b,那么分母b/a就是起点,因为b/a的分数太大,起始点已经超过了a/b,没有什么意义:1/(b/a)=a/b ,假设起点s<b/a,那么显而易见,起点的分数已经比我们要的总和(a/b)大了。 
    4.比较简单的限制结尾可以这样看:如果我已经找到分母k了,而现在要分解得分数是a/b,现在还要找m个单位分数,那么可以想象:有可能 m * ( 1/k ) 还小于a/b,也就是说就算全是1/k,我凑够m个,也达不到a/b,那么说明前面的分配方案肯定有无,直接可以return了。加上这个剪枝已经可以得到答案了,只是时间有点慢罢了。 
    5。现在我们假设终点为t,还要找m个单位分数,现在的分数剩下a/b,那么很容易有m * (1/t) <= a / b  ,也就是说我如果m个都用最小的,肯定小于等于a/b。(等于号就是说有可能m=1,我可能直接终点就是答案,如果m>1,那么终点肯定也不可能选到,假设选了(后面还要选(m-1)个,肯定凑不够)这样子,由上面的式子,经过变换,可以得到 t >= m*b/a ,也就是说终点为m*b/a。 
    a<b<1000

    #include<bits/stdc++.h>
    using namespace std;
    long long n,m,h,ji[11],jians[11];
    inline int g(long long a,long long b)
    {
      int c=a%b;
      while(b)
      {
        c=a%b;
        a=b;b=c;
      }
      return a;
    }
    inline bool cha(long long a,long long b,int shen)
    {
      if(a==0)
      return 1;
      if(a==1&&shen==1)
      {
        ji[shen]=b;return 1;
      }
      if(shen!=1&&shen!=2)
      {
        bool da=0;
        for(int i=b/a+1;i<=b/a*shen;i++)
        {
          ji[shen]=i;
          if(shen*b>=i*a&&ji[shen]>ji[shen+1])
          {
            int gcd=g(a*i-b,b*i);
            if(cha((a*i-b)/gcd,b*i/gcd,shen-1)==1)
            {
              da=1;
              if(shen==2&&(jians[1]==0||jians[1]>ji[1]))
              for(int j=1;j<=h;j++)
                jians[j]=ji[j];
            }
          }
       }
       return da;
      }
      if(shen==1||shen==2)
      {
        bool da=0;
        for(int i=b/a*shen;i>=b/a+1;i--)
        {
          ji[shen]=i;
          if(shen*b>=i*a&&ji[shen]>ji[shen+1])
          {
            int gcd=g(a*i-b,b*i);
            if(cha((a*i-b)/gcd,b*i/gcd,shen-1)==1)
            {
              da=1;
              if(shen==2&&(jians[1]==0||jians[1]>ji[1]))
              for(int j=1;j<=h;j++)
                jians[j]=ji[j];
            }
          }
        }
      return da;
      }
    }
    int main()
    {
      cin>>n>>m;
      h=1;
      while(cha(n,m,h)==0)
      {
        h++;
      }
      for(int i=h;i>=1;i--)
        cout<<jians[i]<<" ";
    }

    //低估这道题了,十点半没刷出来

  • 相关阅读:
    【loj2639】[Tjoi2017]不勤劳的图书管理员
    【bzoj3514】Codechef MARCH14 GERALD07加强版
    BZOJ1002【FJOI2007】轮状病毒
    数论基础(附加例题)
    表达式总结
    背包
    hdu1027
    hdu1026
    hdu1025
    hdu1024
  • 原文地址:https://www.cnblogs.com/fanhao050109/p/10890243.html
Copyright © 2020-2023  润新知