7月11日

糕手小鱼發表於2024-07-12

今日刷題

https://www.luogu.com.cn/problem/P4377

01揹包+精度二分+分數規劃 將t[i]與w[i]的比值化為t[i] - x * w[i];二分這個X。(這也是分數規劃的經典)

本題特殊在於要求重量之和>=K, 所以要用01揹包的思想來解決,權值便成了t[i] - x * w[i];判斷其>或<0,二分邊界移動

如果本題降低難度,就是要選取k個比值,那麼就可以用貪心的思想找前k個大的t[i] - x * w[i],判斷其>或<0,二分邊界移動。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=300;
int n,k;
int w[N],t[N];
double f[1010];
bool check(double x) {
    for (int i = 1; i <= k; i++) f[i] = -1e8;
    for (int i = 1; i <= n; i++) {
        for (int j = k; j >= 0; j--) {
            int s = min(k, j + w[i]);
            f[s] = max(f[s], f[j] + t[i] - x * w[i]);
        }
    }
    return f[k] >= 0;
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> w[i] >> t[i];
    }
    double l = 0, r = 1000;
    while (r - l > 1e-5) {
        double mid = (l + r) / 2;
        if (check(mid)) l = mid;
        else r = mid;
    }
    int ans = 1000 * l;
    cout << ans << endl;
    return 0;
}