nyoj914Yougth的最大化(二分搜索 + 贪心)

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 
来源 
Yougth 

 


题解: 
Yougth的最大化 
这道题目是一道0-1分数规划求最优值。 
方法是一个二分搜索+贪心的题目。 
出这道题目就是告诉大家二分不仅可以查找,还可以搜索一个更优值。 
要使得单位重量的价值最大,则其最大不超过单个中最大的单位重量的价值,最小当然不小于0. 
那么我们就这一在0–最大单位重量的价值中间找一个值ans,使得ans为满足题目条件的最大值。如果满足条件,则可以找更大的。设置一个条件。既二分搜索、 
从n个物品中找k个使得k个的价值和/质量和>=ans 
为了使得ans尽可能的大,那么这里就要贪心选择。 
代码详见:

#include <cstdio>

#include <algorithm>

using namespace std;

const int N = 11000;

int w[N],v[N];

double y[N];

int n,c;

int chack(double x)

{

    for(int i=0;i<n;i++)

    {

        y[i]=v[i]-x*w[i];

    }

    sort(y,y+n);

    double sum=0;

    for(int i=0;i<c;i++)

    {

        sum+=y[n-i-1];

    }

    return sum>=0;

}

double reaerch(double enf)

{

    double l=0,r=enf,mid;

    for(int i=0;i<100;i++)

    {

        mid=(l+r)/2;

        if(chack(mid))

            l=mid;

        else

            r=mid;

    }

    return l;

}

int main()

{

    while(~scanf("%d%d",&n,&c))

    {

        double ma=0;

        for(int i=0;i<n;i++){

            scanf("%d%d",&w[i],&v[i]);

            double cmp=v[i]/w[i];

            if(cmp>ma)

                ma=cmp;

        }

        printf("%.2lf\n",reaerch(ma));

    }

    return 0;

}
View Code

 

你可能感兴趣的:(you)