完全背包变形,外加排序,要学会变通,本题特殊之处:背包容量就是背包价值,要求的就是最大的背包容量,这需要我们找到真正的限制条件—物品数量和物品放置的限高
题目链接
AC code
#include<bits/stdc++.h>using namespace std;const int M = 1e6;
int dp[M], h[M], a[M], c[M];int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n;cin >> n;for (int i = 1;i <= n;i++)cin >> h[i] >> a[i] >> c[i];for (int i = 1;i < n;i++) {//数据弱就没用sortfor (int j = i + 1;j <= n;j++) {if (a[i] > a[j]) {swap(a[i], a[j]);swap(h[i], h[j]);swap(c[i], c[j]);}}}/* for (int i = 1;i <= n;i++) {//原版完全背包for (int k = 1;k <= c[i];k++) {for (int j = a[i];j >= h[i];j--) {dp[j] = max(dp[j], dp[j - h[i]] + h[i]);}}}int ans = 0;for (int i = 1;i <= a[n];i++) ans = max(ans, dp[i]);cout << ans; */for (int i = 1;i <= n;i++) {//二进制优化写法int num = min(c[i], a[i] / h[i]);for (int k = 1;num > 0;k <<= 1) {if (k > num)k = num;num -= k;for (int j = a[i];j >= h[i] * k;j--) {dp[j] = max(dp[j], dp[j - h[i] * k] + h[i] * k);}}}int ans = 0;for (int i = 1;i <= a[n];i++) ans = max(ans, dp[i]);cout << ans;return 0;
}