题解 | #购物单#

购物单

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

全部评论

相关推荐

Twilight_m...:表格简历有点难绷。说说个人看法: 1.个人基本情况里好多无意义信息,什么婚姻状况、健康状况、兴趣爱好、户口所在地、身份证号码、邮政编码,不知道的以为你填什么申请表呢。 2.校内实践个人认为对找工作几乎没帮助,建议换成和测开有关的项目,实在没得写留着也行。 3.工作经历完全看不出来是干什么的,起码看着和计算机没啥关系,建议加强描述,写点你在工作期间的实际产出、解决了什么问题。 4.个人简述大而空,看着像AI生成,感觉问题最大。“Python,C,C++成为我打造高效稳定服务的得力工具”、“我渴望凭借自身技术知识与创新能力,推动人工智能技术的应用发展,助力社会实现智能化转型”有种小学作文的美感。而且你确定你个人简述里写的你都会嘛?你AI这块写的什么“深入研究”,发几篇顶会的硕博生都不一定敢这么写。而且你AI这块的能力和软测也完全无关啊。个人简述建议写你对哪些技术栈、哪些语言、哪些生产工具的掌握,写的有条理些,而且最好是和测开强相关的。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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