zoukankan      html  css  js  c++  java
  • 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;
    }
    君子知命不惧,自当日日自新
  • 相关阅读:
    SKAction类
    SpriteKit所有的类
    Reachability下载地址
    IOS学习教程
    SpriteKit游戏开发
    APP开发者到期续费说明
    Unique Paths
    Letter Combinations of a Phone Number
    Reverse Nodes in k-Group
    Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/xuxiaojin/p/9418405.html
Copyright © 2011-2022 走看看