POJ3111 K Best(二分 最大化平均值)

来源:互联网 发布:魔塔盒子获取数据失败 编辑:程序博客网 时间:2024/06/05 09:46


http://poj.org/problem?id=3111


TLE了好几次的原因,快排对于已经有一定顺序的数排得比较快,所以要在上次排好的基础上,继续下一次排序。还有就是不用每一次都把新的选择保存下来,最后直接输出b[i].num就可以,因为100次循环以后,最后几次前k个b[i].num就是正解。


一般而言,二分查找的时候左开右闭或者左闭右开都是无所谓的,初始状态中的l,r都不可能是最后答案。一般而言mid一定要能够包括进闭合的那一边。

#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<iostream>#include<algorithm>#define N 100005#define INF 0x3f3f3f3fstruct Node{    double vl, w, v;    int num;};double l, r, mid;int n, k;Node b[N];using namespace std;bool cmp(Node x, Node y){    return x.vl > y.vl;}bool ok(double x){    for (int i = 0; i < n; i++)    {        b[i].vl = b[i].v - x * b[i].w;    }    sort(b, b+n, cmp);    double s = 0;    for (int i = 0; i < k; i++) s += b[i].vl;    if (s >= 0)        return true;    else return false;}int main(){    while (~scanf("%d%d", &n, &k))    {        for (int i = 0; i < n; i++)        {            scanf("%lf%lf", &b[i].v, &b[i].w);            b[i].num = i+1;        }        l = 0;        r = INF;        for (int i = 0; i < 100; i++)        {            mid = (l + r) / 2;            if (ok(mid)) l = mid;            else r = mid;        }        for (int i = 0; i < k-1; i++) printf("%d ", b[i].num);        printf("%d\n", b[k-1].num);    }    return 0;}


0 0
原创粉丝点击