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

猜你喜欢

转载自www.cnblogs.com/xuxiaojin/p/9418405.html
今日推荐