题解 | #购物单#

购物单

http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

解题方法

定义数据结构

  1. 明显看出需要定义Good类,包含v,p,q,fj1,fj2这几个字段,默认字段值为0.为了方便后续构造,实现有参构造函数和无参构造函数。(注意:无参构造函数容易漏掉)
  2. Good[] 来存储1~m+1行数据。(注意:最好把Good[] goods=new Good[m+1],否则后续操作容易数组越界)

动态规划

  1. 问题是求最值,首先想到动态规划
  2. 题目具有重叠子问题,明显的状态是总钱数N与可购买的数量m,又由于需要实时改变Good,定义dp(int N,Good[] goods)

输入字段处理

  1. 采用Scanner和string.split和Integer.valueOf处理输入字段。(注意:不要写while(sc.hasNextLine()),不然处理会出问题)
  2. 对于附件Good要找到主件Good对应字段初始化(注意:记得new Good())

代码思路

  1. 定义dp[N+1][goods.length],base case可以简单理解为总钱数为0或可购买数量为0时,dp[][]也为0
  2. 双层for循环遍历,讨论几种情况,求最大值: 2.1 是附件 2.2 是主件 2.2.1 是主件没有附件 2.2.2 是主件有附件1 2.2.3 是主件有附件2 2.2.4 是主件有附件1和附件2
import java.util.*;
public class Main{
    static class Good{
        public int v;
        public int p;
        public int q;
        public int fj1=-1;
        public int fj2=-1;
        public Good(int v,int p,int q){
            this.v=v;
            this.p=p;
            this.q=q;
        }
        public Good(){
            
        }
    }
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
            String firstLine=sc.nextLine();
            String[] split=firstLine.split(" ");
            int N=Integer.valueOf(split[0]);
            int m=Integer.valueOf(split[1]);
            Good[] goods=new Good[m+1];
            for(int i=1;i<m+1;i++){
                String otherLine=sc.nextLine();
                String[] split2=otherLine.split(" ");
                int v=Integer.valueOf(split2[0]);
                int p=Integer.valueOf(split2[1]);
                int q=Integer.valueOf(split2[2]);
                if(goods[i]!=null){
                    goods[i].v=v;
                    goods[i].p=p;
                    goods[i].q=q;
                }else{
                    goods[i]=new Good(v,p,q);
                }
                // 设置主件的附件
                if(goods[i].q>0){
                    if(goods[goods[i].q]==null){
                        goods[goods[i].q]=new Good();
                    }
                    if(goods[goods[i].q].fj1==-1){
                        goods[goods[i].q].fj1=i;
                    }else{
                        goods[goods[i].q].fj2=i;
                    }
                }
            }
            dp(N,goods);
        
    }
    public static void dp(int N,Good[] goods){
       int[][] dp=new int[N+1][goods.length];
       for(int i=1;i<goods.length;i++){
           int v=-1,v1=-1,v2=-1,v3=-1,temp=-1,temp1=-1,temp2=-1,temp3=-1;
           v=goods[i].v;
           temp=v*goods[i].p;
           if(goods[i].fj1!=-1&&goods[i].fj2!=-1){
               v3=v+goods[goods[i].fj1].v+goods[goods[i].fj2].v;
               temp3=temp+goods[goods[i].fj1].v*goods[goods[i].fj1].p+goods[goods[i].fj2].v*goods[goods[i].fj2].p;
           }
           if(goods[i].fj1!=-1){
               v1=v+goods[goods[i].fj1].v;
               temp1=temp+goods[goods[i].fj1].v*goods[goods[i].fj1].p;
           }
           if(goods[i].fj2!=-1){
               v2=v+goods[goods[i].fj2].v;
               temp2=temp+goods[goods[i].fj2].v*goods[goods[i].fj2].p;
           }
           for(int j=1;j<N+1;j++){
               if(goods[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]+temp);
                   if(j>=v1&&v1!=-1)dp[j][i]=Math.max(dp[j][i],dp[j-v1][i-1]+temp1);
                   if(j>=v2&&v2!=-1)dp[j][i]=Math.max(dp[j][i],dp[j-v2][i-1]+temp2);
                   if(j>=v3&&v3!=-1)dp[j][i]=Math.max(dp[j][i],dp[j-v3][i-1]+temp3);
               }
           }         
       } 
        System.out.println(dp[N][goods.length-1]); 
    }
    
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务