思路
这题考虑二分答案,既选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); } }