nyoj914 (二分最大化)

来源:互联网 发布:淘宝职业女装红色裙子 编辑:程序博客网 时间:2024/06/04 22:54

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=914

题意:

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


思路:

很可能大家一拿到这个题目就是想到要贪心,算出每一个物品的单位重量价值。

然而这个是segma(vi)/segma(wi),这个想法并不正确。

还是不能理解的话可以看样例:

3 22 25 32 1
0.75如果直接贪心的话就是5 / 7,但是结果是(2 + 1)/(2 + 2) = 0.75 > 5 / 7;用挑战上的思路:枚举答案进行二分。假设d是小于ans的一个值,那么d符合segma(vi)/segma(wi) >= d,那么变换为 segma(vi - wi * d) >= 0;所以在进行计算的时候要针对每一个d进行排序,然后取出k个来。Code:
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int maxn = 1e4 + 10;struct Node{    double x,y;    double val;}a[maxn];bool cmp(Node _x,Node _y){    return _x.val > _y.val;}int n,m;double calc(double d){    for(int i = 1; i <= n; i ++)        a[i].val = a[i].y - d * a[i].x;    sort(a+1,a+n+1,cmp);    double ret = 0;    for(int i = 1; i <= m; i ++)    {        ret += a[i].val;    }    return ret;}int main(){    while( ~ scanf("%d%d",&n,&m))    {        for(int i = 1; i <= n; i ++)            scanf("%lf%lf",&a[i].x,&a[i].y);        double l = 0,r = 1e6;        int T = 60;        while(T --)        {            double mid = (l + r) / 2;            if(calc(mid) >= 0)                l = mid;            else r = mid;        }        printf("%.2f\n",l);    }    return 0;}


原创粉丝点击