- 二维费用的背包可以和 0/1背包,完全背包,多重背包…结合
- 本题是和 0/1 背包结合
有 N N N 件物品和一个容量是 V V V 的背包,背包能承受的最大重量是 M M M 。
每件物品只能用一次,体积是 v i v_{i} vi ,重量是 m i m_{i} mi,价值是 w i w_{i} wi 。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最 大。
输出最大价值。
分析
- 集合:所有从前 i i i 个物品中选,总体积不超过 j j j ,总重量不超过 k k k 的所有选法的集合
- 属性: M a x ( w ) Max(w) Max(w)
- 状态表示:设 f [ i , j , k ] f[i,j,k] f[i,j,k] 为从前 i i i 个物品中选,总体积不超过 j j j ,总重量不超过 k k k 选出物品的最大价值
- 状态计算:
f
[
i
,
j
,
k
]
=
m
a
x
(
f
[
i
−
1
,
j
,
k
]
,
f
[
i
−
1
,
j
−
v
[
i
]
,
k
−
m
[
i
]
]
+
w
[
i
]
)
f[i,j,k]=max(f[i-1,j,k],f[i-1,j-v[i],k-m[i]]+w[i])
f[i,j,k]=max(f[i−1,j,k],f[i−1,j−v[i],k−m[i]]+w[i])
- 表示不选或者选第 i i i 个物品
- 求最后一步: a n s = f [ N , V , M ] ans=f[N,V,M] ans=f[N,V,M]
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1500;
int N, Vol, M;
int f[maxn][maxn];
int main() {
scanf("%d%d%d", &N, &Vol, &M);
for(int i = 0; i < N; i++) {
int vol, m, w;
scanf("%d%d%d", &vol, &m, &w);
for(int j = Vol; j >= vol; j--) {
for(int k = M; k >= m; k--) {
f[j][k] = max(f[j][k], f[j - vol][k - m] + w);
}
}
}
printf("%d\n", f[Vol][M]);
return 0;
}