• poj3296--Rinse(三分)


    题目链接:点击打开链接

    题目大意:有一个酒桶容量为Vc。里面还有Vw的酒,如今用Vb的水去刷酒桶,每次酒桶的内壁上会留下Vr的液体,最多能够刷k次,问怎么样刷酒桶。能够让酒桶里面的就最少。

    假设Vb+Vw < Vc,那么直接输出0

    那么其他情况就保证了一定能够向外倒水。所以终于的桶里面剩余的液体是Vr。仅仅要保证Vr内的酒的浓度最小。那么剩余的酒也就是最少的。

    能够假设用的水是x1,x2,x3,,,,计算每次刷通后的浓度。

    第一次刷:Vw / (Vw+x1)

    第二次刷:Vw / (Vw+x1) * Vr / (Vr+x2)

    第三次刷:Vw / (Vw+x1) * Vr / (Vr+x2) * Vr / (Vr+x3)

    这样也就能看出来,假设洗刷k次,那么终于的浓度是Vw / (Vw+x1) * Vr / (Vr+x2) * Vr / (Vr+x3),,,,* Vr / (Vr+xk)

    那么怎样保证它的值最小呢?假设我们能确定一个x1,那么x2+x3,,,+xk = Vb-x1,这种条件怎么保证Vr / (Vr+x2) * Vr / (Vr+x3),,,,* Vr / (Vr+xk)尽量小。我们能够发现,假设x2 = x3 = x4 ,, = xk计算出的结果会比不同的更小,假设x的值都是(Vb-x1)/(k-1),那么k越大,得到的值就越小。(Vb-x1)/(k-1)越大,那么得到的值越小。

    所以选择最多的刷洗次数,从第2次到第k次,每次用水同样,那么剩下的就是x1怎么确定。

    假设x1添加。那么Vw / (Vw+x1)会减小。(Vb-x1)/(k-1)会减小,(Vr/(Vr+x))^(k-1)就会增大,总的浓度不能确定,所以用三分查找,找到一个最小的结果。

    注意

    1、三分的时候桶内的就有Vw。注意三分的上下界。

    2、在计算浓度的时候,向桶内加的水由Vb-x算出,可是这个值不能超多Vc-Vr

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std ;
    #define eqs 1e-9
    int k ;
    double vb , vw , vr , vc ;
    double solve(double x) {
        double ans = vw/(vw+x) ;
        if( k > 1 ) {
            double y = min( (vb-x)/(k-1), vc-vr) ;
            for(int i = 1 ; i < k ; i++)
                ans *= vr/(vr+y) ;
        }
        return ans ;
    }
    int main() {
        while( scanf("%d", &k) != EOF ) {
            if(k == 0) break ;
            scanf("%lf %lf %lf %lf", &vb, &vw, &vr, &vc) ;
            if( vr-vw-vb > eqs ) {
                printf("0
    ") ;
                continue ;
            }
            double low = max(0.0,vr-vw) , mid1 , mid2 , high = min(vb,vc-vw) ;
            while( low + eqs < high ) {
                mid1 = (low + high)/2.0 ;
                mid2 = (mid1 + high)/2.0 ;
                if( solve(mid1) > solve(mid2) ) {
                    low = mid1 ;
                }
                else
                    high = mid2 ;
            }
            printf("%d", k) ;
            printf(" %.2f", high) ;
            if( k > 1 ) high = min(vc-vr,(vb-low)/(k-1)) ;
            for(int i = 1 ; i < k ; i++) {
                printf(" %.2f", high) ;
            }
            printf("
    ") ;
        }
        return 0 ;
    }
    


  • 相关阅读:
    Mysql元数据分析
    python编码encode和decode
    自己写的Python数据库连接类和sql语句拼接方法
    【甘道夫】Sqoop1.99.3基础操作--导入Oracle的数据到HDFS
    SVN配置以及自己主动部署到apache虚拟文件夹
    css中使用id和class 的不同
    Android OpenGL ES(七)----理解纹理与纹理过滤
    一键安装 redmine on windows 和发邮件设置
    足球大数据:致足球怀疑论者-The Counter(s)-Reformation反教条改革
    【Android进阶篇】Fragment的两种载入方式
  • 原文地址:https://www.cnblogs.com/llguanli/p/8460225.html
Copyright © 2020-2023  润新知