import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int V = scanner.nextInt(); List<int[]> items = new ArrayList<>(); for (int i = 0; i < n; i++) { int v = scanner.nextInt(); int w = scanner.nextInt(); items.add(new int[]{v, w}); } int[] dp1 = new int[V + 1]; Arrays.fill(dp1, 0); for (int[] item : items) { int v = item[0]; int w = item[1]; for (int j = v; j <= V; j++) { if (dp1[j - v] + w > dp1[j]) { dp1[j] = dp1[j - v] + w; } } } int ans1 = dp1[V]; int[] dp2 = new int[V + 1]; Arrays.fill(dp2, Integer.MIN_VALUE); dp2[0] = 0; for (int[] item : items) { int v = item[0]; int w = item[1]; for (int j = v; j <= V; j++) { if (dp2[j - v] != Integer.MIN_VALUE) { dp2[j] = Math.max(dp2[j], dp2[j - v] + w); } } } int ans2 = dp2[V] == Integer.MIN_VALUE ? 0 : dp2[V]; System.out.println(ans1); System.out.println(ans2); } }
https://www.nowcoder.com/discuss/727521113110073344
思路:
- 输入处理:读取物品数量n和背包体积V,以及每个物品的体积和价值,存储在列表中。
- 普通完全背包问题:初始化dp1数组为0,表示每个体积可以装的最大价值初始为0。遍历每个物品,更新每个体积的最大价值。对于每个物品的体积v和价值w,从体积v开始到V,更新可能的更大价值。
- 恰好装满的完全背包问题:初始化dp2数组为负无穷,表示不可达状态,只有dp2[0]为0,表示恰好装满体积0的价值为0。同样遍历每个物品,但只有在当前体积减去物品体积的状态可达时,才更新当前状态。
- 输出结果:分别输出普通背包问题和恰好装满背包问题的最大价值结果。