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。同样遍历每个物品,但只有在当前体积减去物品体积的状态可达时,才更新当前状态。
- 输出结果:分别输出普通背包问题和恰好装满背包问题的最大价值结果。



京公网安备 11010502036488号