有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si
件,每件体积是 vi
,价值是 wi
。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N
,V
,用空格隔开,分别表示物品种数和背包容积。
接下来有 N
行,每行三个整数 vi
,wi
,si
,用空格隔开,分别表示第 i
种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤100
0<vi,wi,si≤100
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
AC:
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int N = sc.nextInt();
int V = sc.nextInt();
int[] v = new int[N + 1];
int[] w = new int[N + 1];
int[] s = new int[N + 1];
int[][] dp = new int[N + 1][V + 1];
for (int i = 1; i <= N; i++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
s[i] = sc.nextInt();
}
for (int i = 1; i <= N; i++) {
for (int j = V; j >= 0; j--) {
for (int k = 0; k <= s[i]; k++) {
if (j >= k * v[i])
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - k * v[i]] + k * w[i]);
}
}
}
System.out.println(dp[N][V]);
}
}
}
思路:
现在有a件物品,每件物品都有它自己的价值与体积,
因为每件只能放一次,那么咱们就按先后顺序一个一个拿起来判断,看能不能装下,
若是能装下,看要不要拿,要不要拿肯定是看此时拿了的话能否构成此时的最优解。
要判断是否是该状态下的最优解肯定要判断如果将该物品放入刚好满的话,
那放他之前的最优解是什么。
转换一下思维就是要求以 “背包容积-该物品容积
为容积的背包装之前的物品的最优解【并不包括本物品以及之后的物品】。
那么咱们就要通过从1遍历背包的容积来判断最优解,
这就是所谓的基于之前的数据。
现在总结下思路
咱们要做这道题就要挨个物品判断要不要拿能不能拿,
同时通过遍历背包容积判断每个容积下的最优解,
以此来判断该种物品究竟拿了能不能带到此时的最优解。
用二维数组dp[i-1][x]
,就可以完美的表示第i件物品之前容积为x时的最优解(第i
件物品和它后面的物品都不可能在这个背包)