题解 | #购物单#

购物单

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

这样的题只配中等难度吗?那困难级别的得多变态呀。。。

在搞懂了0/1背包问题,完全背包问题,多重背包问题之后,在明知道这道题就是背包问题的扩展,应该使用动态规划解决的背景下,耗时40多分钟,仍然无法想到一个应用简单类型就能解决此题的方案。最终只好新建一个类来解决,再耗时1小时才解决此问题。

此题最大的难点在于:如何在加入附件的时候确定主件已经加入了,如何在处理附件2的时候确定附件1或者主件是否加入了,如何确定主件,主件+附件1,主件+附件2和主件+所有附件哪个才是最优解。

我的方案是使用一个自定义的类来记录主附件之间的关系,数组中只会记录主件,附件随同主件一起处理。


import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] values = scanner.nextLine().split(" ");
        int money = Integer.parseInt(values[0]) / 10;
        int count = Integer.parseInt(values[1]);
        Good[] goods = new Good[count + 1];
        for (int i = 1; i <= count; i++) {
            values = scanner.nextLine().split(" ");
            int price = Integer.parseInt(values[0]) / 10;
            int weight = Integer.parseInt(values[1]);
            int index = Integer.parseInt(values[2]);
            if (index == 0) { // master 才放
                Good good = goods[i];
                if (good == null) {
                    goods[i] = new Good(price, weight);
                } else {
                    good.price = price;
                    good.weight = weight;
                }
            } else {
                Good master = goods[index];
                if (master == null) {
                    master = new Good();
                    goods[index] = master;
                }
                master.slaves.add(new Good(price, weight));
            }
        }
        System.out.println(plan1(money, goods));
    }

    private static int plan1(int money, Good[] goods) {
        int[] dp = new int[money + 1];
        for (int i = 1; i < goods.length; i++) {
            Good master = goods[i];
            if (master == null) {
                continue;
            }
            for (int j = money; j >= master.price; j--) {
                // 单独主
                int masterValue = master.price * master.weight;
                int masterOnly = dp[j - master.price] + masterValue;
                dp[j] = Math.max(dp[j], masterOnly);
                if (master.slaves.size() == 0) {
                    continue;
                }
                // 主+1
                Good slave0 = master.slaves.get(0);
                int price0 = master.price + slave0.price;
                if (j >= price0) {
                    int masterAndOne = dp[j - price0] + masterValue + slave0.price * slave0.weight;
                    dp[j] = Math.max(dp[j], masterAndOne);
                }
                if (master.slaves.size() == 1) {
                    continue;
                }
                // 主+2
                Good slave1 = master.slaves.get(1);
                int price1 = master.price + slave1.price;
                if (j >= price1) {
                    int masterAndTwo = dp[j - price1] + masterValue + slave1.price * slave1.weight;
                    dp[j] = Math.max(dp[j], masterAndTwo);
                }

                // 主+1+2
                int priceAll = master.price + slave0.price + slave1.price;
                if (j >= priceAll) {
                    int all = dp[j - priceAll] + masterValue + slave0.price * slave0.weight + slave1.price * slave1.weight;
                    dp[j] = Math.max(dp[j], all);
                }
            }
        }
        return dp[money] * 10;
    }

    private static class Good {
        int price;
        int weight;
        List<Good> slaves = new ArrayList<>(2);

        Good() {
        }

        Good(int price, int weight) {
            this.price = price;
            this.weight = weight;
        }
    }

}
全部评论

相关推荐

不愿透露姓名的神秘牛友
2025-12-17 16:48
今天九点半到公司,我跟往常一样先扫了眼电脑,屁活儿没有。寻思着没事干,就去蹲了个厕所,回来摸出手机刷了会儿。结果老板刚好路过,拍了我一下说上班别玩手机,我吓得赶紧揣兜里。也就过了四十分钟吧,我的直属领导把我叫到小隔间,上来就给我一句:“你玩手机这事儿把老板惹毛了,说白了,你可以重新找工作了,等下&nbsp;HR&nbsp;会来跟你谈。”&nbsp;我当时脑子直接宕机,一句话都没憋出来。后面&nbsp;HR&nbsp;找我谈话,直属领导也在旁边。HR&nbsp;说我这毛病不是一次两次了,属于屡教不改,不光上班玩手机,还用公司电脑看论文、弄学校的事儿。我当时人都傻了,上班摸鱼是不对,可我都是闲得发慌的时候才摸啊!而且玩手机这事儿,从来没人跟我说过后果这么严重,更没人告诉我在公司学个习也算犯错!连一次口头提醒都没有,哪儿来的屡教不改啊?更让我膈应的是,昨天部门刚开了会,说四个实习生里留一个转正,让大家好好表现。结果今天我就因为玩手机被开了。但搞笑的是,开会前直属领导就把我叫去小会议室,明明白白告诉我:“转正这事儿你就别想了,你的学历达不到我们部门要求,当初招你进来也没打算给你这个机会。”合着我没入贵厂的眼是吧?可我都已经被排除在转正名单外了,摸个鱼至于直接把我开了吗?真的太离谱了!
rush$0522:转正名单没进,大概率本来就没打算留你
摸鱼被leader发现了...
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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