链接:https://ac.nowcoder.com/acm/problem/14662
来源:牛客网

小咪是一个土豪手办狂魔,这次他去了一家店,发现了好多好多(n个)手办,但他是一个很怪的人,每次只想买k个手办,而且他要让他花的每一分钱都物超所值,即:买下来的东西的总价值/总花费=max。请你来看看,他会买哪些东西吧。

分数规划,二分答案
有 n 个物品,有属性值 ai,bi要求选出至多 k 个物品,使得sum(ai) / sum(bi)尽可能大。
我们要首先二分答案 x,若 sum(ai) / sum(bi) ≥x 则说明答案可以更大。
稍微变形一下:sum(a[i]) >= sum(b[i]) * x;
继续:sum(a[i] - b[i] * x) >= 0

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
typedef long long ll;
ll a[maxn], b[maxn], c[maxn];
int n, k;
 
bool cmp(ll a, ll b) {
    return a > b;
}
 
int check(int x) {
    for (int i = 1; i <= n; i++) {
        c[i] = b[i] - a[i] * x;
    }
    sort (c + 1, c + n + 1, cmp);
    ll ans = 0;
    for (int i = 1; i <= k; i++) { //取最大的k个
        ans += c[i];
    }
    return ans >= 0; //判断 sum(b[i] - a[i] * x) >=0 -> 答案l = mid + 1 else r = mid - 1
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n >> k;
        int l = 0, r = 10000;
        for (int i = 1; i <= n; i++) {
            cin >> a[i] >> b[i];;
        }
        while (l <= r) { //二分答案
            int mid = (l + r) / 2;
            if (check(mid)) {
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        cout << l - 1 << endl;
    }
    return 0;
}