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\n") ;
            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("\n") ;
    }
    return 0 ;
}

版权声明:转载请注明出处:http://blog.csdn.net/winddreams

时间: 2024-10-22 13:24:31

poj3296--Rinse(三分)的相关文章

hdu 4717 The Moving Points(三分)

题目链接:hdu 4717 The Moving Points 题意: 在二维平面上有n个点,每个点给出移动的方向和速度. 问在某个时刻,这些点中最大距离最小是多少,输出时刻和距离. 题解: 我们可以知道,每个点对的距离要么是单调递增,要么是有一个峰的函数. 举例画一下可知道合成的这个函数最多只有一个峰,所以可以用三分求解. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespa

三分算法

三分算法 二分算法解决的是具有单调性的问题. 三分算法解决的是抛物线的类型,上凸,下凹. mid=(Left+Right)/2; midmid=(Right+mid)/2; 题目类型有: HDU :3400  2298  4454  2438  3756 POJ:  3301   3737 ZOJ: 3203

uvalive 4986(三分查找)

题意:空间内有n个点,求一个最小体积的圆锥把所有点包进去.输出圆锥的高和底面半径.圆锥的底面圆心在(0,0),所有点的z坐标都大于等于0. 题解:因为圆锥体积是 V = 1/3 * π * r^2 * h ,这是一个二次函数,也就是个凸性函数,可以用三分查找的方式枚举两个高,然后找到对应的最小的r,比对两个高得到的体积继续三分查找. #include <cstdio> #include <cstring> #include <algorithm> #include &l

Toxophily-数论以及二分三分

G - Toxophily Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2298 Description The recreation center of WHU ACM Team has indoor billiards, Ping Pang, chess and bridge, toxophily, deluxe ballroom

三分 --- CSU 1548: Design road

Design road Problem's Link:   http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1548 Mean: 目的:从(0,0)到达(x,y).但是在0~x之间有n条平行于y轴的河,每条河位于xi处,无限长,wi宽,并分别给出了建立路和桥每公里的单价 求:到达目标的最小费用. analyse: 比赛的时候一直没想到思路,第二个样列怎么算都算不对,赛后才知道是三分. 首先把所有的桥移到最右端,然后三分枚举路和河的交点. Time

csu 1548: Design road (三分)

题意:需要从(0,0) 点 到(x,y) 修一段路 其中有n条和y轴平行的河 修路的单位成本c1 修桥的单位成本c2 问最小总成本为多少 思路:把所有河合并 再三分桥的长度 求出最小成本 #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<stdlib.h> #include<algorithm> #include<queu

HDU 2438 Turn the corner (计算几何 + 三分)

Turn the corner Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2059    Accepted Submission(s): 785 Problem Description Mr. West bought a new car! So he is travelling around the city. One day h

三分查找

我们都知道 二分查找 适用于单调函数中逼近求解某点的值. 如果遇到凸性或凹形函数时,可以用三分查找求那个凸点或凹点. 下面的方法应该是三分查找的一个变形. 如图所示,已知左右端点L.R,要求找到白点的位置. 思路:通过不断缩小 [L,R] 的范围,无限逼近白点. 做法:先取 [L,R] 的中点 mid,再取 [mid,R] 的中点 mmid,通过比较 f(mid) 与 f(mmid) 的大小来缩小范围. 当最后 L=R-1 时,再比较下这两个点的值,我们就找到了答案. 1.当 f(mid) >

POJ 3301 Texas Trip (三分)

题目链接 题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点.输出面积. 思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变. 正方形从0度到180度变化的过程中,把所有点覆盖,面积肯定是有一个最小峰值,是一个凸函数.因此可以用三分法解决.这里有一个难点就是已知两个定点的x,y坐标,过这两个点做两条平行线,平行线并与x轴成d度的角,怎么算出两条平行线的距离. d1 = fabs(cos(d)*(yi-yj)-sin(d)*(xi-x

三分题目

zoj 3203 题意:求人从左到右走影子的最大长度L. 设人离开灯的长度为x,当灯.人的头顶和墙角在一条直线上时(此时人在A点),影子全部投在地上,此时x = (H-h)*D/H;当人继续向前走,一部分影子就会投在墙上,当人走到最右边,影子长度即为人的高度.所以从A点到墙角,人的影子长度先增大后减小,是一个凸性函数.根据两个相似三角形把L表示成x的函数L= D+H-x-(H-h)*D/x,然后三分求解最大值. #include <stdio.h> #include <iostream&