暴力解法(TLE)
#include <iostream>
#include <algorithm>
using namespace std;
int N, V;
const int MAXN = 110;
int v[MAXN], w[MAXN], s[MAXN];
int f[MAXN][MAXN];
int main() {
cin >> N >> V;
for(int i = 1; i <= N; ++i) {
cin >> v[i] >> w[i] >> s[i];
}
for(int i = 1; i <= N; ++i) {
for(int j = 0; j <= V; ++j) {
for(int k = 0; k <= s[i] && j >= v[i] * k; ++k) {
f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + w[i] * k);
}
}
}
cout << f[N][V];
}
二进制优化:
#include <iostream>
#include <algorithm>
using namespace std;
int N, V;
const int MAXN = 11010;
int v[MAXN], w[MAXN];
int f[MAXN];
int m = 1;
int main() {
cin >> N >> V;
for(int i = 1; i <= N; ++i) {
int volume, weight, sum;
cin >> volume >> weight >> sum;
for(int cnt = 1; sum >= cnt; cnt *= 2) {
v[m] = volume * cnt;
w[m] = weight * cnt;
++m;
sum -= cnt;
}
if(sum > 0) {
v[m] = volume * sum;
w[m] = weight * sum;
++m;
}
}
for(int i = 1; i <= m - 1; ++i) {
for(int j = V; j >= v[i]; --j) {
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
cout << f[V];
}
原理:将一种物品按数量拆分为1、2、4、8、16...为一组形成新物品,转化为01背包问题。