题解 | #购物单#
购物单
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);
}
}
