【牛客刷题HJ16】购物单

本文介绍了牛客网的一道购物单题目,该题目类似0-1背包问题,但涉及主件与附件的关系。分析了四种购买情况:只买主件、买主件+附件一、买主件+附件二、买主件+附件一+附件二。文章通过创建物品类,初始化价格、重要度和附件属性,然后使用动态规划方法求解最大满意度,同时对代码进行优化提高运行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、题目描述

二、题目分析

1、题目理解

2、题目分析

(1)首先,将物品类准备好

(2)然后,对v、p、q进行初始化

(3)对动态规划数组进行赋值(填表)

三、总结


一、题目描述

来源:购物单_牛客题霸_牛客网

 

二、题目分析

该题类似于0-1背包问题,关于0-1背包请看0-1背包-动态规划算法_哔哩哔哩_bilibili

1、题目理解

1、购买附件必须买主件,且一个主件最多有两个附件,每件物品只能购买一次;

2、每件物品有三个属性:价格v、重要度p、是主件还是附件q,满意度是价格v和重要度p的数学期望,q为该附件所属主件的编号,q=0表示该物品是主件;

3、手中有N元钱,要买m件物品,使得产生的满意度最大。

2、题目分析

该题与0-1背包相比,难点在于该题有附件关联着,买附件还必须要买主件,有四种情况要讨论:

1、只买主件;

2、买主件+附件一;

3、买主件+附件二;

4、买主件+附件一+附件二;

因为一个主件最多有两个不同的附件,因此两个附件要分开讨论,那么我们遍历物品的时候,可以略过附件,只在买主件的时候考虑附件的情况。

(1)首先,将物品类准备好

包含上述所说的三个属性v、p、q,另外为了区分附件一和附件二,再加两个属性a1和a2分别代表附件一和附件二,初始化为0表示为主件,并生成相应的set方法,方便对a1和a2进行修改,生成有参构造,以便对物品初始化,toString方法是为了方便调试。

class Goods {
    int v; //价格
    int p; //重要度
    int q; //是否为附件

    int a1 = 0, a2 = 0;

    public Goods(int v, int p, int q) {
        this.v = v;
        this.p = p;
        this.q = q;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "v=" + v +
                ", p=" + p +
                ", q=" + q +
                ", a1=" + a1 +
                ", a2=" + a2 +
                '}';
    }

    public void setA1(int a1) {
        this.a1 = a1;
    }

    public void setA2(int a2) {
        this.a2 = a2;
    }
}

(2)然后,对v、p、q进行初始化

新建方法maxValueShop(int[][] list, int N),传入控制台输入的参数,list为代表物品的二维数组,N为预算,也就是手中拥有的钱数,首先对接收的物品信息作初始化,新建一维数组v[]、p[]、q[]接收对应的值,list[i][0]表示价格放入v[]中,list[i][1]表示重要度放入p[]中,list[i][2]表示是主件还是附件放入q[]中,类似于0-1背包,三个数组新建的时候,长度要比物品数量大1,因为有一个0作为初始值,同样物品类数组goods[]长度也要大1,用以上的三个数组来构造物品类,因为刚刚构造的物品类主件都不包含附件a1和a2,需要对a1和a2进行初始化,以上实现代码如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值