zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    小技巧
    常用的交互设计软件
    Android studio 使用SVN需要忽略的文件
    android studio 使用SVN 锁定文件,防止别人修改(基于Android studio 1.4 )
    git 和 github 关系?
    Double 数据保留两位小数一:五舍六入
    设计模式
    Java中关于日期类那些方法
    ios 开源免费接口
    华为招聘机试整理5:简单四则运算
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10003611.html
Copyright © 2011-2022 走看看