• codevs 1288 埃及分数 (迭代加深搜索)


    题目大意:给你一个分数$a/b$,把它拆解成$sum_{i=1}^{n}1/ai$的形式,必须保证$ai$互不相同的情况下,尽量保证n最小,其次保证分母最大的分数的分母最小

    什么鬼玄学题!!!

    因为要保证$n$最小,所以从小到大遍历最大层数$n$,令$a'/b'$表示当前剩余的需要被拆解的数

    如果当前分数的数量等于$n$,更新最优解并返回,继续搜总层数为$n$的所有情况,然后输出答案,因为这一层的最优解一定是全局最优解

    每次选择一个数$i$,表示当前层的数选择了$i$,把剩余的数改成$a'/b'-1/i$进入下一层

    显然暴力枚举$i$会$T$,那就加一些玄学的剪枝

    1.i要大于等于$left lceil b/a ight ceil$,否则就剩余负数了

    2.为了减少枚举次数,可以保证前几层选择的数升序排列,所以$i$要大于$now[dep-1]$

    3.$(n-dep)/i+1/i>=a'/b'$,因为后几层选择的数都小于等于$1/i$,所以后几层和的最大值要大于等于$a'/b'$

    有了这几个玄学的剪枝,我们就能以$O($能过$)$的复杂度通过本题!

     1 #include <map>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define NN 5010
     7 #define MM 2000
     8 #define ll long long 
     9 #define uint unsigned int
    10 #define ull unsigned long long 
    11 using namespace std;
    12 
    13 ll A,B;
    14 int K=500;
    15 ll now[NN],ans[NN];
    16 ll gcd(ll x,ll y){if(!y)return x;return gcd(y,x%y);}
    17 const ll maxn=666666666666ll;
    18 void dfs(int dep,ll a,ll b,int ma)
    19 {
    20     if(dep==ma+1){
    21         if(a>0) return;
    22         if(now[ma]<ans[ma])
    23             for(int i=1;i<=ma;i++)
    24             ans[i]=now[i];
    25         return;
    26     }
    27     ll na,nb,g;
    28     for(ll i=max(now[dep-1]+1,(b/a)+(b%a==0?0:1));a*i<=(ma-dep+1)*b;i++){
    29         na=a*i-b,nb=b*i;
    30         g=gcd(na,nb);
    31         now[dep]=i;
    32         dfs(dep+1,na/g,nb/g,ma);
    33         now[dep]=0;
    34     }
    35 }
    36 
    37 int main()
    38 {
    39     //freopen("t2.in","r",stdin);
    40     scanf("%lld%lld",&A,&B);
    41     for(int k=1;k<=K;k++)
    42         ans[k]=maxn;
    43     for(int k=1;k<=K;k++)
    44     {
    45         dfs(1,A,B,k);
    46         if(ans[k]<maxn){
    47             for(int i=1;i<=k;i++)
    48                 printf("%lld ",ans[i]);
    49             puts("");
    50             break;
    51         }
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10003611.html
Copyright © 2020-2023  润新知