思路

这题考虑二分答案,既选k个物品总价值与总重量的比值

价值 图片说明 等式两边同时乘图片说明可以得到图片说明

我们要所选的k个总单位价值最大,即要选的数量中图片说明 最大,所以二分的check函数对图片说明按降序排列,算出前k个之和是否大于0,大于0就说明当前单位价值可以到达,反之不能

代码

#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define pb push_back
#define pll pair<ll,ll>
#define INF 0x3f3f3f3f
const int mod = 100000000;
const int maxn = 100005;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
struct node{
    int a,b;
    double c;
    bool operator < (const node & A) const {
        return c > A.c;
    }
}q[100005];
int n,k;
bool check(double x){
    for(int i = 0 ; i < n ; ++i) q[i].c = q[i].b - q[i].a*x;
    sort(q,q+n);
    double ans = 0;
    for(int i = 0 ; i < k ; ++i){
        ans += q[i].c;
    }
    return ans >= 0;
}
int main(){
    int t = read();
    while(t--){
        n = read();k = read();
        for(int i = 0 ; i < n ; ++i){
            q[i].a = read();
            q[i].b = read();
        }
        double l = 0,r = 1e9,ans;
        for(int i = 0 ; i < 100 ; ++i){
            double mid = (l + r) / 2;
            if(check(mid)) ans = mid,l = mid;
            else r = mid;
        }
        printf("%.2f\n",ans);
    }
}