一个非常简洁的二进制优化自用板子
根据y总讲的AcWing7. 混合背包问题整理的板子,相当简洁还省空间
空间复杂度无需$O(n \log n)$,降为$O(max(n, log s))$
时间复杂度还是$O(n^2log n)$
#include <iostream>
using namespace std;
const int N = 2010;
int dp[N];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int v, w, s;
cin >> v >> w >> s;
for (int k = 1; k <= s; k *= 2) // 把s拆成二进制形式,如 10 = 2^0 + 2^1 + 2^2 + 3
{
for (int j = m; j >= k * v; j--) // 对上面的分开形式进行01背包
{
dp[j] = max(dp[j], dp[j - k * v] + k * w);
}
s -= k;
}
if (s) { // 处理刚刚拆开的二进制的最后一位
for (int j = m; j >= s * v; j--)
{
dp[j] = max(dp[j], dp[j - s * v] + s * w);
}
}
}
cout << dp[m] << endl;
return 0;
}