// N<=1000, s<=2000 constint N = 15000; int n, m; int f[N], w[N], v[N];
intmain(){ cin >> n >> m; int cnt = 0; for (int i = 1; i <= n; i++) { int a, b, s; cin >> a >> b >> s; int k = 1; for (int k = 1; k <= s; k *= 2) { // 把 k 个物品放在一起 cnt++; v[cnt] = k*a; w[cnt] = k*b; // 这 k 个物品分完了,从总物品中减去 s -= k; } if (s > 0) { cnt++; v[cnt] = s*a; w[cnt] = s*b; } } // 这里更新成 cnt 个物品 n = cnt; for (int i = 1; i <= n; ++i) { for (int j = m; j >= v[i]; --j) { f[j] = max(f[j], f[j-v[i]] + w[i]); } } cout << f[m] << endl; return0; }
intmain(){ ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { int v, w, s; cin >> v >> w >> s; if (s == -1) s = 1; elseif (s == 0) s = N;
for (int r = 0; r < v; r++) { int tt = -1, hh = 0; for (int j = r; j <= m; j += v) { #define val(x) (f[i-1][x] + (j-x)/v*w) if (hh <= tt && j - q[hh] > s*v) hh++; while (hh <= tt && val(q[tt]) <= val(j)) tt--; q[++tt] = j; f[i][j] = val(q[hh]); } } } cout << f[n][m];
intmain(){ ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { int v, w, s; cin >> v >> w >> s; if (s == 0) { // 完全背包 for (int j = v; j <= m; j++) f[j] = max(f[j], f[j-v]+w); } else { // 多重背包 if (s == -1) s = 1; for (int k = 1; k <= s; k <<= 1) { for (int j = m; j >= k*v; j--) { f[j] = max(f[j], f[j-k*v]+w*k); } s -= k; } if (s) { for (int j = m; j >= s*v; j--) { f[j] = max(f[j], f[j-s*v]+s*w); } } } } cout << f[m]; return0; }
constint N = 110; int n, m; int w[N][N], v[N][N], s[N], f[N];
intmain(){ cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> s[i]; for (int j = 1; j <= s[i]; j++) { cin >> v[i][j] >> w[i][j]; } } for (int i = 1; i <= n; i++) { for (int j = m; j >= 1; j--) { for (int k = 0; k <= s[i]; k++) { if (j >= v[i][k]) f[j] = max(f[j], f[j-v[i][k]] + w[i][k]); } } } cout << f[m] << endl; return0; }
同样,对于这个可以进行优化,把 f 变成一维数组。
1 2 3 4 5 6 7
for (int i = 1; i <= n; i++) { for (int j = m; j >= 1; j--) { for (int k = 0; k <= s[i]; k++) { if (j >= v[i][k]) f[j] = max(f[j], f[j-v[i][k]] + w[i][k]); } } }
由于这里用了 i-1 层的数据,所以需要自右向左遍历。
二维费用的背包问题
有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。输出最大价值。