今日刷題
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; }