洛谷P4653 [CEOI2017]Sure Bet

题目

https://www.luogu.com.cn/problem/P4653

思路

最大化可能的最小收益,最大值最小,想必大家已经熟悉二分题的这个套路了。枚举一个值x,模拟,检验是否能选A和选B的收益都达到x。

显然要先选权值大的灯,所以我们降序排序。

关于这个检验,我用的是最暴力的方法,若A不行,就加到它行;再看B,也是如此。注意因为选取灯泡有花费,成本变高,这时A又不一定可行了,之后我们反复横跳,直到AB都满足条件。

若可以出现AB都满足的情况,则该x值可行。

代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define inf 0x3f3f3f3f
#define eps 1e-6
#define maxn (int)(1e6+10)
#define db double
using namespace std;
int n;
db a[maxn],b[maxn];
int ok(db x){
    int i=0,j=0;
    db suma=0,sumb=0;
    while(suma-i-j<x||sumb-i-j<x){
        while(suma-i-j<x){
            if(i>n) return 0;
            suma+=a[++i];
        }
        while(sumb-i-j<x){
            if(j>n) return 0;
            sumb+=b[++j];
        }
    }
    return 1;
}
bool cmp(db x,db y){
    return x>y;
}
int main(){
    int i,j;
    db l,r,mid;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%lf%lf",&a[i],&b[i]);
    sort(a+1,a+n+1,cmp);
    sort(b+1,b+n+1,cmp);
    l=0;r=inf;
    while(r-l>eps){
        mid=(l+r)/2.0;
        if(ok(mid)) l=mid;
        else r=mid;
    }
    printf("%.4lf",l);
    // system("pause");
    return 0;
}
posted @ 2020-12-01 19:31  文艺平衡树  阅读(128)  评论(0编辑  收藏  举报