Java 题解 | #购物单#

购物单

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

先参考了一下评论区的思想,就是分成了不选择附件、选择一个附件(附件1或附件2)、选择两个附件三种情况,然后就是0-1背包问题了。

import java.util.*;

public class Main {


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        List<LinkedList<int[]>> goods = new ArrayList<>(m);
        for (int i = 0; i < m; i++) {
            goods.add(new LinkedList<>());
        }
        for (int i = 0; i < m; i++) {
            int num1 = scanner.nextInt();
            int num2 = scanner.nextInt();
            int num3 = scanner.nextInt();
            if (num3 == 0) {
                goods.get(i).addFirst(new int[]{num1, num2});
            } else {
                //附件添加到末尾
                goods.get(num3-1).addLast(new int[]{num1, num2});
            }
        }
        //移出空的good
        goods.removeIf(AbstractCollection::isEmpty);
        int[] dp = new int[n + 1];
        for (int i = 0; i < goods.size(); i++) {
            LinkedList<int[]> good = goods.get(i);
            for (int j = n; j >= good.get(0)[0]; j--) {
                //不管有没有附件,这步都要执行
                dp[j] = Math.max(dp[j], dp[j - good.get(0)[0]] + good.get(0)[1] * good.get(0)[0]);
                if (good.size() > 1) {
                    //选择一个附件,附件数大于1,选择一个附件这步都要执行
                    //选择一个附件有两种可能,选择附件1或者附件2,由于大于1 这里情况为选择附件1
                    if (j >= (good.get(0)[0] + good.get(1)[0])) {
                        dp[j] = Math.max(dp[j], dp[j - good.get(0)[0] - good.get(1)[0]] + good.get(0)[1] * good.get(0)[0] + good.get(1)[1] * good.get(1)[0]);
                    }

                }
                if (good.size() > 2) {
                    //同上选择一个附件有两种可能,选择附件1或者附件2,由于大于2 这里情况为选择附件2
                    if (j >= (good.get(0)[0] + good.get(2)[0])) {
                        dp[j] = Math.max(dp[j], dp[j - good.get(0)[0] - good.get(2)[0]] + good.get(0)[1] * good.get(0)[0] + good.get(2)[1] * good.get(2)[0]);
                    }
                    //选择两个附件 附件数大于2,选择两个附件这步都要执行
                    if (j >= (good.get(0)[0] + good.get(1)[0]+good.get(2)[0])) {
                        dp[j] = Math.max(dp[j], dp[j - good.get(0)[0] - good.get(1)[0] - good.get(2)[0]] + good.get(0)[1] * good.get(0)[0] + good.get(1)[1] * good.get(1)[0]+good.get(2)[1] * good.get(2)[0]);
                    }
                }
            }

        }
        System.out.println(dp[n]);

    }

}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务