• NYOJ 914 Yougth的最大化


    Yougth的最大化

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:4
    描写叙述

    Yougth如今有n个物品的重量和价值各自是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗?

    输入
    有多组測试数据
    每组測试数据第一行有两个数n和k。接下来一行有n个数Wi和Vi。


    (1<=k=n<=10000) (1<=Wi,Vi<=1000000)

    输出
    输出使得单位价值的最大值。(保留两位小数)
    例子输入
    3 2
    2 2
    5 3
    2 1
    例子输出
    0.75

    分析:

    要想取得单位重量价值最大,须要在0-Max之间二分搜索。Max为随意选物品所得的单位重量最大价值。

    Max = max(v[i] / w[i] | i = 0...n - 1)。

    为什么Max如此取值,以下证明:

    如果一对vi。wi 满足: vi / wi = max(v[i] / w[i] | i = 0......n-1),任取一对 vk。wk (k != i),则有vi / wi > vk / wk,

    即:vi * wk > vk * wi 把它记为公式1。

    证明:

    要证的是 (vi + vk1 +...+ vk2) / (wi + wk1 +...+ wk2) <= vi / wi, (0<=k1<=k2<=n-1 && k1 != i && k2 != i),

    1.当k1 = k2 = 0 时,即不添加。上式等号成立。

    2.为便于证明,此处仅仅添加vk(k != i),它具有普通性。即证(vi + vk) / (wi + wk) < vi / wi,

    即wi(vi + vk) < vi(wi + wk)。也就是vi * wk > vk * wi,此式即为公式1。成立!

    3.当添加2......n-1 个数时也成立。

    4.证毕。

    对于cleck(a)若不理解见代码以下具体解释。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 10000 + 5;
    double x[maxn], w[maxn], v[maxn];   //全定义为double,便于计算
    int n, k;
    bool cleck(double a){
        for(int i = 0; i < n; i++) x[i] = v[i] - a * w[i];
        sort(x, x + n);
        double sum = 0;
        for(int i = 0; i < k; i++) sum += x[n - i - 1];  //贪心,由大到小取
        return sum >= 0 ?

    true : false; } int main() { while(~scanf("%d%d", &n, &k)){ double Max = 0; for(int i = 0; i < n; i++){ scanf("%lf%lf", &w[i], &v[i]); Max = max(Max, v[i] / w[i]); } double L = 0, R = Max; while(R - L > 1e-4){ //二分查找最优值 double M = (L + R) / 2; if(cleck(M)) L = M; else R = M; } printf("%.2lf ", L); } return 0; }


    cleck(a)为检查单位重量价值a是否可取。若可取。需满足

    (vk1 +...+ vk2) / (wk1 +...+ wk2) >= a (0<=k1<=k2<=n-1),

    即vk1 +...+ vk2 >= a(wk1 +...+ wk2),

    即vk1 - a * wk1 +...+ vk2 - a * wk2 >= 0

    所以尽量取vki - a * wki(即代码中xi)大的才有可能满足。

  • 相关阅读:
    C阶段【01】
    Xcode常用快捷键的使用
    eclipse中添加web app libraries
    hibernate 连接SQL SERVER2008
    hibernate配置入门(个人总结)
    项目编译PNG报错
    项目archive打包编译报错
    项目上传
    Git本地项目上传,版本管理工具与GitHub的简单结合使用
    将制定目录下的内容复制到另一个路径下
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5175149.html
Copyright © 2020-2023  润新知