import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextInt();//物品数量 int v = input.nextInt();//背包容量 int[] vol = new int[n + 1]; //体积 int[] val = new int[n + 1]; //价值 for (int i = 0; i < n; i++) { vol[i + 1] = input.nextInt(); val[i + 1] = input.nextInt(); } //求解问题1: //01背包问题,dp[i] 表示背包容量为i时能放的最大价值。 //对每个物品进行遍历,放不下的时候继承之前的,放得下的时候进行判断,如果放进去,总价值会不会比同容量的其他情况大 //如果更大,就放进去。 //最后的dp【v】就是想要的结果 int[] dp = new int[v + 1]; for (int i = 1; i <= n; i++) { //从1开始,且数组长度为i+1,既是防止数组越界,又是将默认的0作为初始状态 for (int j = v; j >= vol[i]; j--) { dp[j] = Math.max(dp[j], dp[j - vol[i]] + val[i]); } } System.out.println(dp[v]); //求解问题2: //思路:要么在将背包装满的各种可能里找最大的,要么在价值从大到小的可能中找第一个能装满的。 Arrays.fill(dp, Integer.MIN_VALUE); dp[0] = 0; //将dp【0】置为0, 将其余的置为负数极限 //这是为了恰好装满的条件, //这样可以保证,如果到容量为v时不是正好装满,就一定时INF + maxVal,小于零 for (int i = 1; i <= n; i++) { for (int j = v; j >= vol[i]; j--) { dp[j] = Math.max(dp[j], dp[j - vol[i]] + val[i]); } } if(dp[v] < 0){ dp[v] = 0; } System.out.println(dp[v]); } }