題目鏈接:https://www.luogu.com.cn/problem/P4377
解題思路:
映射關係:
- \(w_i \rightarrow b_i\);
- \(t_i \rightarrow a_i\)。
問題轉變成了01分數規劃問題。但是有一個限制,就是 \(\sum w_i \times b_i \ge W\)。
可以考慮01揹包。把 \(b_i\) 作爲第 \(i\) 個物品的重量,\(a_i - mid \times b_i\) 作爲第 \(i\) 個物品的價值,然後問題就轉化爲揹包了。
那麼 \(dp[n][W]\) 就是最大值。
一個要注意的地方: \(\sum w_i \times b_i\) 可能超過 \(W\) ,此時直接視爲 \(W\) 即可。
示例代碼:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 255, maxw = 1010;
int n, W, a[maxn], b[maxn];
double f[maxw];
bool check(double mid) {
f[0] = 0;
for (int i = 1; i <= W; i ++) f[i] = -1e9;
for (int i = 1; i <= n; i ++) {
for (int j = W; j >= 0; j --) {
int k = min(j+b[i], W);
f[k] = max(f[k], f[j] + a[i] - mid * b[i]);
}
}
return f[W] >= 0;
}
int main() {
cin >> n >> W;
for (int i = 1; i <= n; i ++) cin >> b[i] >> a[i];
double L = 0, R = 1000;
while (R - L > 1e-5) {
double mid = (L + R) / 2;
if (check(mid)) L = mid;
else R = mid;
}
cout << (int) (1000 * L) << endl;
return 0;
}