最大化平均值

来源:互联网 发布:2017嘉实基本面50 知乎 编辑:程序博客网 时间:2024/04/29 06:57

题意:

有n个物品的重量和价值分别是wi和vi。从中选出k个物品使得单位重量的价值最大

输入:

3        2

2 2

5 3

2 1

输出:

0.75

 

分析:

一般最先想到的方法可能是把物品按照单位价值进行排序,从小到大贪心的进行选取,但是这个方法对于样例输入得到的结果是5/7=0.714.所以这个方法是不可行的。实际上,对于这个问题使用二分搜索法可以很好的解决。我们定义

条件C(x):=可以选择使得单位重量的价值不小于x

因此原问题就变成了求满足C(x)的最大的x。

#include <cstdio>#include <algorithm>using namespace std;const int maxn = 10000 + 10;const int INF = 100000000;int n, k;int w[maxn], v[maxn];double y[maxn];   // v - x * w//判断是否满足条件bool C(double x){    for (int i = 0; i < n; i++){        y[i] = v[i] - x * w[i];    }    sort(y, y + n);    //计算y数组中从大到小前k个数的和    double sum = 0;    for (int i = 0; i < k; i++){        sum += y[n - i - 1];    }    return sum >= 0;}void solve(){    double lb = 0, ub = INF;    for (int i = 0; i < 100; i++){        double mid = (lb + ub) / 2;        if (C(mid))            lb = mid;        else            ub = mid;    }    printf("%.2lf\n", ub);}int main(){    scanf("%d%d", &n, &k);    for (int i = 0; i < n; i++){        scanf("%d%d", &w[i], &v[i]);    }    solve();    return 0;}


0 0
原创粉丝点击