题意 : 给出 N 个物品的价值和重量,然后要求选出 K 个物品使得选出来物品的单位重量价值最大,最后输出被选物品的编号。

分析 : 

很容易去想先算出每个物品的单位价值然后升序排序取前 K 个,但是很可惜这样的做法是错误的。

例如 : N = 3、K = 2、{ w、v } = { {2,2}、{5,4}、{2,1} },贪心的方法是选出 1、2,但是正确答案是选出1、3

这题的正确做法是利用二分,难点就在如何判定二分出来的每一个单位重量价值是否是一个可行答案

假设当前二分出来的答案是 x

那么就要求选出来的某 K 个物品的组合使得 ∑ vi / ∑ wi ≥ x 成立

变形得到 ∑ ( vi - wi * x ) ≥ 0

那么最后就变成了对于当前的 x 对所有物品的 vi - wi * x 进行排序

并判断前 K 大的是否大于等于 0 ,如果是则说明可行!

#include<algorithm>
#include<stdio.h>
#include<math.h>
using namespace std;
;
;
;
struct Jewel{ int id, v, w; }arr[maxn];
struct st{
    double val; int id;
    bool operator < (const st & rhs) const{
        return this->val > rhs.val;
    };
}c[maxn];
int N, K, ans[maxn];

bool OK(double key)
{
    ; i<=N; i++){
        c[i].val = arr[i].v - arr[i].w * key;
        c[i].id = arr[i].id;
    }
    sort(c+, c++N);
    ;
    ; i<=K; i++)
        sum += c[i].val;
    if(sum >= 0.0){
        ; i<=K; i++)
            ans[i] = c[i].id;
        return true;
    }else return false;
}

int main(void)
{
    while(~scanf("%d %d", &N, &K)){
        ; i<=N; i++){
            if(i <= K) ans[i] = i;///注意要提前给 ans 赋上初值,因为 OK 函数可能永远不为真,例如所有物品的 v = 0
            arr[i].id = i;
            scanf("%d %d", &arr[i].v, &arr[i].w);
        }

        double L = 0.0;
        double R = INF;
        while(R - L > EPS){
            double mid = ( R + L ) / 2.0;
            if(OK(mid)) L = mid;
            else R = mid;
        }

        ; i<=K; i++){
            printf("%d", ans[i]);
            if(i < K) putchar(' ');
            else putchar('\n');
        }
    }
    ;
}

POJ 3111 K Best ( 二分 )的更多相关文章

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

    poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件 ...

  2. POJ 3111 K Best(01分数规划)

    K Best Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 9876   Accepted: 2535 Case Time ...

  3. POJ 3111 K Best(二分答案)

    [题目链接] http://poj.org/problem?id=3111 [题目大意] 选取k个物品,最大化sum(ai)/sum(bi) [题解] 如果答案是x,那么有sigma(a)>=s ...

  4. POJ - 3111 K Best 0-1分数规划 二分

    K Best Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 12812   Accepted: 3290 Case Time ...

  5. POJ 3111 K Best 最大化平均值 [二分]

    1.题意:给一共N个物品,每个物品有重量W,价值V,要你选出K个出来,使得他们的平均单位重量的价值最高 2.分析:题意为最大化平均值问题,由于每个物品的重量不同所以无法直接按单位价值贪心,但是目标值有 ...

  6. POJ - 3111 K Best(二分)

    包含一些ai和bi的集用S来表示,x = max(sigma(ai)/sigma(bi),i 属于S) ,k 表示S的大小,k= |S|. x和k之间具有单调性.k0 < k1 → x0 ≥ x ...

  7. POJ 3111 K Best

    二分,排序,贪心. 最优比率生成树,可以二分$+$贪心来实现,不过这样做精度不行. 如果是这样一个问题,该如何解决:问你$n$个里面选择$k$个,能否使得$\frac{{\sum\limits_{j ...

  8. poj 3111 K Best (二分搜索之最大化平均值之01分数规划)

    Description Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband ...

  9. POJ 3111 K Best(最大化平均值)

    题目链接:click here~~ [题目大意]有n个物品的重量和价值各自是Wi和Vi.从中选出K个物品使得单位重量的价值最大,输出物品的编号 [解题思路]:最大化平均值的经典.參见click her ...

随机推荐

  1. spring(一) IOC 控制反转 、DI 依赖注入

    IOC 控制反转:创建对象的方式  变成了由Spring来主导 IOC底层原理:对象工厂 1.导入jar包:4个核心jar和1个依赖jar spring-beans-4.3.9.RELEASE.jar ...

  2. C#得到10000以内素数

    偶数除了二都不是素数 一个数 n 如果是合数,那么它的所有的因子不超过sqrt(n)--n的开方 int i, j, n = 10000; for (i = 3; i <= n; i += 2) ...

  3. JS图片宽度自适应移动端

    $(function(){ $("#d-intro").find("img").each(function () {                $(this ...

  4. 深入理解java:1.1. 类加载器

    从java的动态性到类加载机制   我们知道,Java是一种动态语言. 那么怎样理解这个“动态”呢? 或者说一门语言具备了什么特性,才能称之为动态语言呢? 对于java,我是这样理解的. 我们都知道J ...

  5. mysql先分组,然后取每个分组中的第2大的记录

    文章参考http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ 首先建表: ...

  6. Hive-多分隔符

    ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe' WITH SERDEPROPERTIES (&qu ...

  7. 取(2堆)石子游戏 HDU 2177 博弈论

    取(2堆)石子游戏 HDU 2177 博弈论 题意 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中 ...

  8. P3984高兴的津津

    这道题的标签是并查集,但其实是一个并查集思想的模拟题. 被算法标签迷惑了,一直在想怎么存f[],然后怎么查找,但发现其实很难去做.然后就发现其实就是做一个选择就可以了:拿AU的第i次包含在i-1次里, ...

  9. 思维体操: HDU1049Climbing Worm

    Climbing Worm Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  10. java中的数据类型,基本数据类型及其包装类型

    java中的8大基本类型及其包装类型 1,int--->Integer 2,byte--->Byte 3,short--->Short 4,long--->Long 5,cha ...