import java.util.*; /** * NC309 完全背包 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param v int整型 * @param n int整型 * @param nums int整型ArrayList<ArrayList<>> * @return int整型ArrayList */ public ArrayList<Integer> knapsack (int v, int n, ArrayList<ArrayList<Integer>> nums) { // return solution1(v, n, nums); return solution2(v, n, nums); } /** * 动态规划 * * dp[i]表示背包体积为i时的最大价值 * * 1. 背包能装物品的最大价值 * dp[i] = Math.max(dp[i], dp[i-volume]+wealth) , i>=volume * * 2. 背包能装物品的最大价值(背包恰好装满) * { Math.max(dp[i], wealth) , i=volume * dp[i] = { * { Math.max(dp[i], dp[i-volume]+wealth) , i>volume && dp[i-volume]>0 * * @param v * @param n * @param nums * @return */ private ArrayList<Integer> solution1(int v, int n, ArrayList<ArrayList<Integer>> nums){ ArrayList<Integer> result = new ArrayList<Integer>(); int[] dp = new int[v+1]; int volume,wealth; // 1. 背包能装物品的最大价值 for(int i=1; i<=v; i++){ for(int j=0; j<n; j++){ volume = nums.get(j).get(0); wealth = nums.get(j).get(1); if(i >= volume){ dp[i] = Math.max(dp[i], dp[i-volume]+wealth); } } } result.add(dp[v]); // 2. 背包能装物品的最大价值(背包恰好装满) Arrays.fill(dp, 0); for(int i=1; i<=v; i++){ for(int j=0; j<n; j++){ volume = nums.get(j).get(0); wealth = nums.get(j).get(1); if(i == volume){ dp[i] = Math.max(dp[i], wealth); } if(i > volume){ // i-volume能装满 if(dp[i-volume] > 0){ dp[i] = Math.max(dp[i], dp[i-volume]+wealth); } } } } result.add(dp[v]); return result; } /** * 动态规划 * * dp[i][0]表示背包体积为i时的最大价值 * dp[i][1]表示背包体积为i时的最大价值(背包恰好装满) * * 1. 背包能装物品的最大价值 * dp[i][0] = Math.max(dp[i][0], dp[i-volume][0]+wealth) , i>=volume * * 2. 背包能装物品的最大价值(背包恰好装满) * { Math.max(dp[i][1], wealth) , i=volume * dp[i][1] = { * { Math.max(dp[i][1], dp[i-volume][1]+wealth) , i>volume && dp[i-volume][1]>0 * * @param v * @param n * @param nums * @return */ private ArrayList<Integer> solution2(int v, int n, ArrayList<ArrayList<Integer>> nums){ ArrayList<Integer> result = new ArrayList<Integer>(); int[][] dp = new int[v+1][2]; int volume,wealth; // 1. 背包能装物品的最大价值 dp[i][0] // 2. 背包能装物品的最大价值(背包恰好装满) dp[i][1] for(int i=1; i<=v; i++){ for(int j=0; j<n; j++){ volume = nums.get(j).get(0); wealth = nums.get(j).get(1); if(i == volume){ dp[i][0] = Math.max(dp[i][0], dp[i-volume][0]+wealth); dp[i][1] = Math.max(dp[i][1], wealth); } if(i > volume){ dp[i][0] = Math.max(dp[i][0], dp[i-volume][0]+wealth); // i-volume能装满 if(dp[i-volume][1] > 0){ dp[i][1] = Math.max(dp[i][1], dp[i-volume][1]+wealth); } } } } result.add(dp[v][0]); result.add(dp[v][1]); return result; } }