AcWing 7. clean code混合背包问题,清晰易懂,转换为已知简单问题
原题链接
中等
作者:
jyj407
,
2020-08-15 19:11:47
,
所有人可见
,
阅读 655
#include <iostream>
#include <vector>
using namespace std;
struct Good {
int v;
int w;
};
int zeroOnePack(int n, int m, const vector<Good>& goods) {
vector<int> dp(m + 1, 0);
for (const auto& good : goods) {
for (int j = m; j >= good.v; j--) {
dp[j] = max(dp[j], dp[j - good.v] + good.w);
}
}
return dp[m];
}
int main()
{
int t = 1, n, m, wi, vi, s;
cin >> n >> m;
vector<Good> goods;
while(n--) {
cin >> vi >> wi >> s;
int k;
// Break multiple knapsack into 0-1 knapsack using binary split
auto binarySplitToZeroOne = [&]() {
for (k = 1; k <= s; k <<= 1) {
goods.push_back({k * vi, k * wi});
s -= k;
}
if (s > 0) {
goods.push_back({s * vi, s * wi});
}
};
if (s > 0) { // Multiple knapsack
binarySplitToZeroOne();
} else if (s == 0) { // Complete knapsack
s = m / vi; // convert to multiple knapsack
binarySplitToZeroOne();
} else if (s == -1) { // zero one knapsack
goods.push_back({vi, wi});
}
}
auto res = zeroOnePack(n, m, goods);
cout << res <<endl;
return 0;
}