poj 3111 卖珠宝问题 最大化平均值

Posted xuxiaojin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3111 卖珠宝问题 最大化平均值相关的知识,希望对你有一定的参考价值。

题意:有N件分别价值v重量w的珠宝,希望保留k件使得 s=v的和/w的和最大

思路:找到贡献最大的

  1. 设当前的s为mid(x)
  2. 那么贡献就是 v-w*x 排序 ,取前k个

    bool operator<(const node& c) const
    {
    return v - x * w > c.v - x * c.w;
    }

  3. 如果前k的s>mid说明 mid太小 增下限
  4. 如果前k的s<mid说明 mid太大 减上限

解决问题的代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;

#define maxn 100000
double x;
int n, k;

struct node {
    int v, w;
    int id;
    bool operator<(const node& c) const
    {
        return v - x * w > c.v - x * c.w;
    }
}no[maxn];

bool solve(double mid)
{
    x = mid;
    sort(no, no + n);
    double v = 0, w = 0;
    for (int i = 0; i < k; i++)
    {
        v += no[i].v; w += no[i].w;
    }
    return v / w > mid;
}

int main()
{
    double maxs = 0;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++)
    {
        scanf("%d%d", &no[i].v, &no[i].w);
        no[i].id = i + 1;
        maxs = max(maxs, (double)no[i].v / no[i].w);
    }
    double lb = 0, ub = maxs;
    for (int i = 1; i < 50; i++)
    {
        double mid = (lb + ub) / 2;
        if (solve(mid)) lb = mid;
        else ub = mid;
    }
    int ids[maxn];
    for (int i = 0; i < k; i++)
    {
        ids[i] = no[i].id;
    }
    sort(ids, ids + k);
    for (int i = 0; i < k; i++)
        printf("%d ", ids[i]);
    printf("
");
    return 0;
}

 




以上是关于poj 3111 卖珠宝问题 最大化平均值的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3111 K Best 二分 最大化平均值

poj 3111 K Best 最大化平均值 二分思想

POJ 2976 3111(二分-最大化平均值)

最大化平均值POJ3111-K Best

POJ-2976 Dropping tests---二分最大化平均值

POJ 3111 K Best(二分答案)