题解 | #购物单#

购物单

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联系一下,使用滚动数组减小空间

全部评论

相关推荐

昨天 18:38
门头沟学院 运营
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务