题解 | #购物单#
购物单
http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
看大佬的题解之后使用Java写了压缩空间的方法
包括钱数的压缩和dp数组的一维压缩
public class Main { // 状态多一些的01背包问题,每个商品包含价值和权重,分别进行保存 public static void main(String[] args) { Scanner in = new Scanner(System.in); int N = in.nextInt() / 10; //总钱数,节省空间 int m = in.nextInt();// 总物品数目 int[][] prices = new int[m + 1][3]; int[][] weights = new int[m + 1][3]; in.nextLine(); for (int i = 1; i <= m; i++){ int v = in.nextInt() / 10;// 需要的钱 int p = in.nextInt() * v;// 钱*重要度 int q = in.nextInt(); in.nextLine(); if (q == 0){// 主件直接加就行 prices[i][0] = v; weights[i][0] = p; }else if (prices[q][1] == 0){// 从件先试着赋值到主件的第一个位置去 prices[q][1] = v; weights[q][1] = p; }else{// 1号有从件后赋值到从件2 prices[q][2] = v; weights[q][2] = p; } } int[] dp = new int[N + 1];// 压缩空间到1维 for (int i = 1; i <= m; i++){// 遍历所有物品 // 从后向前遍历防止出错,因为这里压缩到了,从前向后的话会将上一行的结果覆盖掉 for (int j = N; j >= 1; j--){ //分为四种情况:只放主,放主1+从1,放主2+从2,放主+从1+从2 int p1 = prices[i][0];// 从件都为0的 int w1 = weights[i][0]; int p2 = prices[i][1]; int w2 = weights[i][1]; int p3 = prices[i][2]; int w3 = weights[i][2]; if (j - p1 >= 0) dp[j] = Math.max(dp[j], dp[j-p1] + w1); if (j - p1 - p2 >= 0) dp[j] = Math.max(dp[j], dp[j - p1 - p2] + w1 + w2); if (j - p1 - p3 >= 0) dp[j] = Math.max(dp[j], dp[j - p1 - p3] + w1 + w3); if (j - p1 -p2 - p3 >= 0) dp[j] = Math.max(dp[j], dp[j - p1 -p2 - p3] + w1 + w2 + w3); } } System.out.println(dp[N] * 10); } }