题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
整合了题解里最高赞的两位大佬的题解,动态规划(空间压缩)的代码运行报错,经过排查出现两个问题:
1.new GOODS();爆红,输出静态方法不能引用非静态变量的异常;
2. if (goods[q-1].a1 == -1) { 最后一个示例报空指针异常——原因是没有全部初始化。比如第一个物品是第五个的附件,那么找不到第五个的a1的值。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static class good {
public int v; //物品的价格
public int p; //物品的重要度
public int q; //物品的主附件ID
public int a1 = -1; //附件1ID
public int a2 = -1; //附件2ID
public good(int v, int p, int q) {
this.v = v;
this.p = p;
this.q = q;
}
public void setA1(int a1) {
this.a1 = a1;
}
public void setA2(int a2) {
this.a2 = a2;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(); //记录总共要买的物品数量
int m = in.nextInt();
good[] goods = new good[m];
for (int i = 0; i < m; i++) {
int v1 = in.nextInt();
int p1 = in.nextInt();
int q1 = in.nextInt();
goods[i] = new good(v1, p1 * v1, q1); //直接计算好价值
}
for (int i = 0; i < m; i++) {
if (goods[i].q > 0) {
if (goods[goods[i].q-1].a1 == -1) {
goods[goods[i].q-1].a1 = i;
} else {
goods[goods[i].q-1].a2 = i;
}
}
}
//转为01背包问题 倒序
int[] dp = new int[N + 1];
for (int i = 1; i <= m;
i++) { //i指的是物品的次序,和goods[]的下标不一致
for (int j = N; j >= 0; j--) {
if (goods[i - 1].q > 0) {
continue;//这是附件,跳过
}
if (j >= goods[i - 1].v) {
//情况一:选/不选该物品
dp[j] = Math.max(dp[j], dp[j - goods[i - 1].v] + goods[i - 1].p);
}
if (goods[i - 1].a1 != -1 && j >= goods[i - 1].v + goods[goods[i - 1].a1].v) {
//情况二:选不选该物品的附件一
dp[j] = Math.max(dp[j], dp[j - goods[i - 1].v - goods[goods[i - 1].a1].v] +
goods[i - 1].p + goods[goods[i - 1].a1].p);
}
if (goods[i - 1].a2 != -1 && j >= goods[i - 1].v + goods[goods[i - 1].a2].v) {
//情况三:选不选该物品的附件二
dp[j] = Math.max(dp[j], dp[j - goods[i - 1].v - goods[goods[i - 1].a2].v] +
goods[i - 1].p + goods[goods[i - 1].a2].p);
}
if (goods[i - 1].a1 != -1 && goods[i - 1].a2 != -1 &&
j >= goods[i - 1].v + goods[goods[i - 1].a1].v + goods[goods[i - 1].a2].v) {
//情况四:选不选该物品的两个附件
dp[j] = Math.max(dp[j], dp[j - goods[i - 1].v - goods[goods[i - 1].a1].v -
goods[goods[i - 1].a2].v] + goods[i - 1].p + goods[goods[i - 1].a1].p +
goods[goods[i - 1].a2].p);
}
}
}
System.out.println(dp[N]);
}
}


