2018年东北农业大学春季校赛 I wyh的物品【01分数规划/二分】

链接:https://www.nowcoder.com/acm/contest/93/I
来源:牛客网

题目描述

wyh学长现在手里有n个物品,这n个物品的重量和价值都告诉你,然后现在让你从中选取k个,问你在所有可能选取的方案中,最大的单位价值为多少(单位价值为选取的k个物品的总价值和总重量的比值)

输入描述:

输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每组测试数据,第一行输入两个数n和k(1<=k<=n<=100000)
接下来有n行,每行两个是a和b,代表这个物品的重量和价值

输出描述:

对于每组测试数据,输出对应答案,结果保留两位小数
示例1

输入

1
3 2
2 2
5 3
2 1

输出

0.75

说明

对于样例来说,我们选择第一个物品和第三个物品,达到最优目的
【分析】:poj经典原题。这里是从中选取k个,求最大的单位价值为多少。01分数规划一般用二分or迭代,先用利益-mid*代价,由大到小排序(二分必须要排序)后,就是求前k个最大和sum,若sum>=0说明合法,即可以得到最大收益。
【代码】:
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-6
double w[100010],v[100010],p[100010];
int n,k;
bool ok(double x){
    for(int i=1;i<=n;++i){
        p[i]=v[i]-x*w[i];
    }
    sort(p+1,p+1+n,greater<double>());
    double s=0;
    for(int i=1;i<=k;++i)
        s+=p[i];
    return s>=0;
}
int main()
{
    int i,j;
    int t;
    cin>>t;
    while(t--){
        cin>>n>>k;
        for(i=1;i<=n;++i){
            scanf("%lf%lf",w+i,v+i);
        }
        double l=0,r=100005;
        while(l+eps<r){
            double m=r-(r-l)/2;
            if(ok(m)){
                l=m;
            }
            else{
                r=m;
            }
        }
        printf("%.2f\n",l);
    }
    return 0;
}
二分

 

posted @ 2018-04-05 23:35  Roni_i  阅读(349)  评论(0编辑  收藏  举报