题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
import java.io.BufferedReader; import java.io.InputStreamReader; public class Main { static class Good { int v; int p; int q; int sub1; int sub2; public Good() { } public Good(int v, int p, int q) { this.v = v; this.p = p; this.q = q; } public int getV() { return v; } public void setV(int v) { this.v = v; } public int getP() { return p; } public void setP(int p) { this.p = p; } public int getQ() { return q; } public void setQ(int q) { this.q = q; } public int getSub1() { return sub1; } public void setSub1(int sub1) { this.sub1 = sub1; } public int getSub2() { return sub2; } public void setSub2(int sub2) { this.sub2 = sub2; } } public static int dw = 100; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); boolean flag = true; // 获取第一行 String line1 = br.readLine(); // 第一行是N,钱的个数 m, 物品的个数 String[] arr = line1.split(" "); int N = Integer.parseInt(arr[0]); int m = Integer.parseInt(arr[1]); Good[] A = new Good[m + 1]; int i = 1; while (null != (line1 = br.readLine())) { arr = line1.split(" "); int v = Integer.parseInt(arr[0]); int p = Integer.parseInt(arr[1]); int q = Integer.parseInt(arr[2]); if (flag) { if (v % dw != 0) { flag = false; dw = 10; for (int j = 1; j < i; j++) { A[j].setV(A[j].v * 10); } } } v = v / dw; // i可能在下面的q>0时已经进行了初始化 if (null != A[i]) { A[i].setV(v); A[i].setP(p); A[i].setQ(q); } else { A[i] = new Good(v, p, q); } if (q > 0) { if (A[q] == null) { A[q] = new Good(); } // 优先填充附件一,再去填充附件二 if (A[q].sub1 == 0) { A[q].setSub1(i); } else { A[q].setSub2(i); } } i++; } N = N / dw; dp(N, A); } public static void dp(int N, Good[] A) { int[][] dp = new int[N + 1][A.length]; for (int i = 1; i < A.length; i++) { // v代表没有附件,v1代表有一个附件sub1.v2代表一个附件2,v3代表2个附件 int v = -1, v1 = -1, v2 = -1, v3 = -1; int tempdp = -1, tempdp1 = -1, tempdp2 = -1, tempdp3 = -1; v = A[i].v; tempdp = v * A[i].p; // 拥有两个附件 if (A[i].sub1 != 0 && A[i].sub2 != 0) { v3 = v + A[A[i].sub1].v + A[A[i].sub2].v; tempdp3 = tempdp + A[A[i].sub1].v * A[A[i].sub1].p + A[A[i].sub2].v * A[A[i].sub2].p; } // 只拥有附件1 if (A[i].sub1 != 0) { v1 = v + A[A[i].sub1].v; tempdp1 = tempdp + A[A[i].sub1].v * A[A[i].sub1].p; } // 只拥有附件2 if (A[i].sub2 != 0) { v2 = v + A[A[i].sub2].v; tempdp2 = tempdp + A[A[i].sub2].v * A[A[i].sub2].p; } for (int j = 1; j < N + 1; j++) { // 并非主件 if (A[i].q > 0) { dp[j][i] = dp[j][i - 1]; } else { dp[j][i] = dp[j][i - 1]; if (j >= v && v != -1) { dp[j][i] = Math.max(dp[j][i], dp[j - v][i - 1] + tempdp); } if (j >= v1 && v1 != -1) { dp[j][i] = Math.max(dp[j][i], dp[j - v1][i - 1] + tempdp1); } if (j >= v2 && v2 != -1) { dp[j][i] = Math.max(dp[j][i], dp[j - v2][i - 1] + tempdp2); } if (j >= v3 && v3 != -1) { dp[j][i] = Math.max(dp[j][i], dp[j - v3][i - 1] + tempdp3); } } } } System.out.println(dp[N][A.length - 1] * dw); } }