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\n", 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)大的才有可能满足。

NYOJ 914 Yougth的最大化,布布扣,bubuko.com

时间: 2024-10-22 12:34:07

NYOJ 914 Yougth的最大化的相关文章

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 思路:

NYIST 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 22 25 32 1 样例输出0.75 来源Yougth 上传者TC

NYOJ Yougth的最大化

http://acm.nyist.net/JudgeOnline/problem.php?pid=914 Yougth的最大化 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗? 输入 有多组测试数据 每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和Vi. (1<=k=n<=10000) (1<=Wi,Vi<=1000000) 输出 输出使

二分搜索(2、Yougth的最大化,无限逼近最大值)

条件C(x):=可以选择是单位重量的价值不小于x,则该问题就变成了满足C(x)的最大的x,那么怎么判断C(x)是否可行呢?假设我们选了某个物品的集合S,那么它们的单位重量价值是: 因此就变成了判断是否存在s满足下面条件: 把这个不等是进行变形就得到 //#define LOCAL #include<cstdio> //#include<iostream>注意引入头文件,编译时候需要连接,是费内存的,如果不需要尽量不要引入 #include<algorithm> int

Yougth的最大化(好题,二分查找 0 1分数规划)

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 1 #in

nyoj 1189 yougth和他的朋友们 (DP)

题目:nyoj 1189 yougth和他的朋友们 这题目是14年北京赛区的原题,讲题的时候说有三种解法,我们是用dp做的当时,原题目链接:Happy Matt Friends 题意就不在说了.因为要求的是满足条件的种数. 我们定义状态dp[i][j]:当我们把第 i 个数放进去之后得到 j 的种数是多少 那么我们可以得到状态转移方程:dp[i][j^ a [ i ] ] += dp[i-1][j] 就是当前得到每个 j ^  a [ i ] 有前 i-1 个数得到.整个dp一遍就是得到结果了.

POJ 3111 K Best &amp;&amp;NYOJ 914 (二分+ 贪心,最大化平均值)

链接:NYOJ:click here, POJ:click here 题意:(最大化平均值,挑战编程P143) 有n个物品的重量和价值分别是w[i]和v[i],从中选出K个物品使得单位重量的价值最大.(1<=k<=n<=10^41<=w[i],v[i]<=10^6) 一般想到的是按单位价值对物品排序,然后贪心选取,但是这个方法是错误的,比如对nyoj的例题来说,从大到小地进行选取,输入的结果是5/7=0.714对于有样例不满足.我们一般用二分搜索来做(其实这就是一个01分数规

问题 L: Yougth的最大化

题目描述 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 1 /*解题思路: 2 3 这道题目是一道0-1分数规划求最优值.方法是一个二分搜索+贪心的题目

Yougth的最大化

1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 6 using namespace std; 7 8 #define N 10010 9 10 double w[N],v[N],ave[N]; 11 int k,n; 12 double max1; 13 14 int check(double x) 15 { 16 double sum