题解 | #购物单#

购物单

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

import java.util.Objects;
import java.util.Scanner;

/**
 * 购物车最大满意度
 * - 其实是0-1的背包问题,就是选择多一点动态规划
 * - 不要陷进附件影响主件的胡同里去
 * - 换个角度考虑,主件带动附件
 *
 * @date 2022/07/06
 */
public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int money = scanner.nextInt();
        int itemNum = scanner.nextInt();
        Goods[] goodsArr = new Goods[itemNum];

        // 初始化
        for (int i = 0; i < itemNum; i++) {
            Goods goods = new Goods();
            goods.setPrice(scanner.nextInt());
            goods.setWeight(scanner.nextInt());
            int pindex = scanner.nextInt();
            goods.setPindex(pindex);
            goodsArr[i] = goods;
        }

        // 设置主附件关系
        for (int i = 0; i < goodsArr.length; i++) {
            Goods goods = goodsArr[i];
            if (goods.mainCheck()) {
                continue;
            }
            Integer pindex = goods.getPindex();
            Goods pg = goodsArr[pindex - 1];
            if (pg.getAttachOne() == null) {
                pg.setAttachOne(i);
            } else {
                pg.setAttachTwo(i);
            }
        }

        // 定义动态数组
        int[][] dp = new int[itemNum + 1][money + 1];

        // 明确base case,买0件满意度都会0,买0元钱都是0,默认

        // 两种状态的遍历
        for (int i = 1; i <= itemNum; i++) {
            for (int j = 1; j <= money; j++) {
                /**
                 * 明确选择,有五种
                 * - 啥都不买
                 * - 买主件
                 * - 买主件和附件1
                 * - 买主件和附件2
                 * - 买主件和附件1、2
                 */
                dp[i][j] = dp[i - 1][j];
                // 后面几种情况都是跟主件相关
                Goods goods = goodsArr[i - 1];
                if (!goods.mainCheck()) {
                    continue;
                }
                if (j >= goods.getPrice()) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - goods.getPrice()] + goods.getGreatWight());
                }
                Integer attachOne = goods.getAttachOne();
                if (Objects.nonNull(attachOne) && attachOne >= 0) {
                    Goods goods1 = goodsArr[attachOne];
                    if (j >= (goods.getPrice() + goods1.getPrice())) {
                        dp[i][j] = Math.max(dp[i][j],
                                dp[i - 1][j - goods.getPrice() - goods1.getPrice()]
                                        + goods.getGreatWight() + goods1.getGreatWight());
                    }
                }

                Integer attachTwo = goods.getAttachTwo();
                if (Objects.nonNull(attachTwo) && attachTwo >= 0) {
                    Goods goods2 = goodsArr[attachTwo];
                    if (j >= (goods.getPrice() + goods2.getPrice())) {
                        dp[i][j] = Math.max(dp[i][j],
                                dp[i - 1][j - goods.getPrice() - goods2.getPrice()]
                                        + goods.getGreatWight() + goods2.getGreatWight());
                    }
                }

                attachOne = goods.getAttachOne();
                attachTwo = goods.getAttachTwo();
                if (Objects.nonNull(attachOne) && attachOne >= 0 && Objects.nonNull(attachTwo) && attachTwo >= 0) {
                    Goods goods1 = goodsArr[attachOne];
                    Goods goods2 = goodsArr[attachTwo];
                    if (j >= (goods.getPrice() + goods1.getPrice() + goods2.getPrice())) {
                        dp[i][j] = Math.max(dp[i][j],
                                dp[i - 1][j - goods.getPrice() - goods1.getPrice() - goods2.getPrice()]
                                        + goods.getGreatWight() + goods1.getGreatWight() + goods2.getGreatWight());
                    }
                }
            }
        }
        System.out.println(dp[itemNum][money]);
    }
    
    static class Goods {

        private int price;

        private int weight;

        private Integer pindex;

        private Integer attachOne;

        private Integer attachTwo;

        public boolean mainCheck() {
            return new Integer(0).equals(pindex);
        }

        public int getGreatWight() {
            return price * weight;
        }

        public Integer getPrice() {
            return price;
        }

        public void setPrice(Integer price) {
            this.price = price;
        }

        public Integer getWeight() {
            return weight;
        }

        public void setWeight(Integer weight) {
            this.weight = weight;
        }

        public Integer getPindex() {
            return pindex;
        }

        public void setPindex(Integer pindex) {
            this.pindex = pindex;
        }

        public Integer getAttachOne() {
            return attachOne;
        }

        public void setAttachOne(Integer attachOne) {
            this.attachOne = attachOne;
        }

        public Integer getAttachTwo() {
            return attachTwo;
        }

        public void setAttachTwo(Integer attachTwo) {
            this.attachTwo = attachTwo;
        }

        @Override
        public String toString() {
            return "Goods{" +
                    "price=" + price +
                    ", weight=" + weight +
                    ", pindex=" + pindex +
                    ", attachOne=" + attachOne +
                    ", attachTwo=" + attachTwo +
                    '}';
        }
    }
}

明确动规的状态是什么,然后再基于对应状态下的情况列出所有的选择,最后就得到了状态转移方程,其实状态转移方程就是所有的选择#刷题#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务