题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int N = in.nextInt();
int m = in.nextInt();
Goods[] goods = new Goods[m];
for (int i = 0; i < m; i++) {
goods[i] = new Goods();
}
for (int i = 0; i < m; i++) {
int v = in.nextInt();
int p = in.nextInt();
int q = in.nextInt();
goods[i].v = v;
goods[i].p = p * v;
if (q > 0) {
goods[i].isMain = false;
if (goods[q - 1].a1 == null) {
goods[q - 1].a1 = goods[i];
} else {
goods[q - 1].a2 = goods[i];
}
} else {
goods[i].isMain = true;
}
}
// 五种情况:根据主件来,因为即使买附件也得必买主件。
// 1. 不买主件i
// 2. 只买主件i
// 3. 买主件i及其附件a1
// 4. 买主件i及其附件a2
// 5. 买主件i及其附件a1\a2
int[][] dp = new int[m + 1][N + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= N; j++) {
dp[i][j] = dp[i - 1][j];
if (!goods[i - 1].isMain){
continue;
}
if(j >= goods[i - 1].v){
dp[i][j] = Math.max(dp[i-1][j], dp[i - 1][j - goods[i - 1].v] + goods[i - 1].p);
}
if (goods[i - 1].a1 != null&&j>=goods[i - 1].v + goods[i - 1].a1.v) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - goods[i - 1].v - goods[i - 1].a1.v]
+ goods[i - 1].p + goods[i - 1].a1.p);
}
if (goods[i - 1].a2 != null&&j>=goods[i - 1].v + goods[i - 1].a2.v) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - goods[i - 1].v - goods[i - 1].a2.v]
+ goods[i - 1].p + goods[i - 1].a2.p);
}
if (goods[i - 1].a2 != null && goods[i - 1].a1 != null&&j>=goods[i - 1].v + goods[i - 1].a1.v + goods[i - 1].a2.v) {
dp[i][j] = Math.max(dp[i][j],
dp[i - 1][j - goods[i - 1].v - goods[i - 1].a1.v - goods[i - 1].a2.v]
+ goods[i - 1].p + goods[i - 1].a1.p + goods[i - 1].a2.p);
}
}
}
System.out.println(dp[m][N]);
}
}
}
class Goods {
int v;
int p;
boolean isMain;
Goods a1;
Goods a2;
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int N = in.nextInt();
int m = in.nextInt();
Goods[] goods = new Goods[m];
for (int i = 0; i < m; i++) {
goods[i] = new Goods();
}
for (int i = 0; i < m; i++) {
int v = in.nextInt();
int p = in.nextInt();
int q = in.nextInt();
goods[i].v = v;
goods[i].p = p * v;
if (q > 0) {
goods[i].isMain = false;
if (goods[q - 1].a1 == null) {
goods[q - 1].a1 = goods[i];
} else {
goods[q - 1].a2 = goods[i];
}
} else {
goods[i].isMain = true;
}
}
// 五种情况:根据主件来,因为即使买附件也得必买主件。
// 1. 不买主件i
// 2. 只买主件i
// 3. 买主件i及其附件a1
// 4. 买主件i及其附件a2
// 5. 买主件i及其附件a1\a2
int[][] dp = new int[m + 1][N + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= N; j++) {
dp[i][j] = dp[i - 1][j];
if (!goods[i - 1].isMain){
continue;
}
if(j >= goods[i - 1].v){
dp[i][j] = Math.max(dp[i-1][j], dp[i - 1][j - goods[i - 1].v] + goods[i - 1].p);
}
if (goods[i - 1].a1 != null&&j>=goods[i - 1].v + goods[i - 1].a1.v) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - goods[i - 1].v - goods[i - 1].a1.v]
+ goods[i - 1].p + goods[i - 1].a1.p);
}
if (goods[i - 1].a2 != null&&j>=goods[i - 1].v + goods[i - 1].a2.v) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - goods[i - 1].v - goods[i - 1].a2.v]
+ goods[i - 1].p + goods[i - 1].a2.p);
}
if (goods[i - 1].a2 != null && goods[i - 1].a1 != null&&j>=goods[i - 1].v + goods[i - 1].a1.v + goods[i - 1].a2.v) {
dp[i][j] = Math.max(dp[i][j],
dp[i - 1][j - goods[i - 1].v - goods[i - 1].a1.v - goods[i - 1].a2.v]
+ goods[i - 1].p + goods[i - 1].a1.p + goods[i - 1].a2.p);
}
}
}
System.out.println(dp[m][N]);
}
}
}
class Goods {
int v;
int p;
boolean isMain;
Goods a1;
Goods a2;
}