题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int money = sc.nextInt();
int m = sc.nextInt();
/**
本质上依然属于0/1背包问题,每个商品都有拿与不拿的选项,在有限资源下获取最大的收益
不同点在于物品分主次,必须整理出附件与主件的关系
*/
if(money<=0||m<=0) System.out.println(0);
Good[] goods=new Good[m+1];
for(int i=1;i<=m;i++){
int v=sc.nextInt();
int p=sc.nextInt();
int q=sc.nextInt();
if(goods[i]==null){
goods[i]=new Good(v,p,q);
}else{
goods[i].v=v;
goods[i].p=p;
goods[i].q=q;
}
if(q>0){
if(goods[q]==null){
goods[q]=new Good(i);
}else{
if(goods[q].a1==0){
goods[q].setA1(i);
}else{
goods[q].setA2(i);
}
}
}
}
int[] dp=new int[money+1];
for(int i=1;i<=m;i++){
for(int j=money;j>=1;j--){
int v1=goods[i].getValue();
int v2=0;
int v3=0;
int v4=0;
if(goods[i].a1>0){
v2=v1+goods[goods[i].a1].getValue();
}
if(goods[i].a2>0){
v3=v1+goods[goods[i].a2].getValue();
}
if(goods[i].a2>0){
v4=v2+goods[goods[i].a2].getValue();
}
if(goods[i].q==0){
int p1=goods[i].v;
if(j>=p1)dp[j]=Math.max(dp[j-p1]+v1,dp[j]);
if(v2>0){
int p2=goods[i].v+goods[goods[i].a1].v;
if(j>=p2)dp[j]=Math.max(dp[j-p2]+v2,dp[j]);
}
if(v3>0){
int p3=goods[i].v+goods[goods[i].a2].v;
if(j>=p3)dp[j]=Math.max(dp[j-p3]+v3,dp[j]);
}
if(v4>0){
int p4=goods[i].v+goods[goods[i].a1].v+goods[goods[i].a2].v;
if(j>=p4)dp[j]=Math.max(dp[j-p4]+v4,dp[j]);
}
}
}
}
System.out.println(dp[money]);
}
private static class Good{
public int v;
public int p;
public int q;
public int a1=0;
public int a2=0;
public Good(int a1){
this.a1=a1;
}
public Good(int v,int p,int q){
this.v=v;
this.p=p;
this.q=q;
}
public int getValue(){
return this.v*this.p;
}
public void setA1(int a1){
this.a1=a1;
}
public void setA2(int a2){
this.a2=a2;
}
@Override
public String toString(){
return "v:"+this.v+",p:"+this.p+",q:"+this.q+",a1:"+this.a1+",a2:"+this.a2;
}
}
}
学习完dp联系一下,使用滚动数组减小空间


