题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { //dp[j]花j元买物品所能达到的最大满意度 Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int m = scan.nextInt(); Good[] goods = new Good[m]; for (int i = 0; i < m; i++) { goods[i] = new Good(); } for (int i = 0; i < m; i++) { int v = scan.nextInt(); int p = scan.nextInt(); int isMain = scan.nextInt(); //设置属性 goods[i].v = v; goods[i].p = v * p; if (isMain == 0) { goods[i].isMain = true; } else if (goods[isMain - 1].a1 == -1) { goods[isMain - 1].a1 = i; } else { goods[isMain - 1].a2 = i; } } int[] dp = new int[n + 1]; //dp[j]花j元买物品所能达到的最大满意度 //dp[0] = 0; //01背包 先遍历物品再遍历背包 背包逆序 for (int i = 0; i < m; i++) { for (int j = n; j >= 0; j--) { //5种情况 //是附件,则不买该物品 if (!goods[i].isMain) { continue; } //是主件,买该物品 if ( j >= goods[i].v) { dp[j] = Math.max(dp[j], dp[j - goods[i].v] + goods[i].p); } //是主件,买该物品以及附件1 if ( goods[i].a1 != - 1 && j >= goods[i].v + goods[goods[i].a1].v) { dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a1].v] + goods[i].p + goods[goods[i].a1].p); } //是主件,买该物品以及附件2 if (goods[i].a2 != - 1 && j >= goods[i].v + goods[goods[i].a2].v) { dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a2].v] + goods[i].p + goods[goods[i].a2].p); } //是主件,买该物品已经两个附件 if (goods[i].a1 != - 1 && goods[i].a2 != - 1 && j >= goods[i].v + goods[goods[i].a1].v + goods[goods[i].a2].v) { dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a1].v - goods[goods[i].a2].v] + goods[i].p + goods[goods[i].a1].p + goods[goods[i].a2].p); } } } System.out.print(dp[n]); } } class Good { int v;//价格 int p;//重要度&满意度 boolean isMain; int a1 = -1;//附件1对应索引 int a2 = -1;//附件2对应索引 }