7月11日
今日刷题
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; }