题解 | #购物单#

购物单

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

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        //dp[j]花j元买物品所能达到的最大满意度
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();

        Good[] goods = new Good[m];
        for (int i = 0; i < m; i++) {
            goods[i] = new Good();
        }

        for (int i = 0; i < m; i++) {
            int v = scan.nextInt();
            int p = scan.nextInt();
            int isMain = scan.nextInt();
            //设置属性
            goods[i].v = v;
            goods[i].p = v * p;
            if (isMain == 0) {
                goods[i].isMain = true;
            } else if (goods[isMain - 1].a1 == -1) {
                goods[isMain - 1].a1 = i;
            } else {
                goods[isMain - 1].a2 = i;
            }
        }

        int[] dp = new int[n + 1];
        //dp[j]花j元买物品所能达到的最大满意度
        //dp[0] = 0;
        //01背包 先遍历物品再遍历背包 背包逆序
        for (int i = 0; i < m; i++) {
            for (int j = n; j >= 0; j--) {
                //5种情况
                //是附件,则不买该物品
                if (!goods[i].isMain) {
                    continue;
                }
                //是主件,买该物品
                if ( j >= goods[i].v) {
                    dp[j] = Math.max(dp[j], dp[j - goods[i].v] + goods[i].p);
                }
                //是主件,买该物品以及附件1
                if ( goods[i].a1 != - 1 && j >= goods[i].v + goods[goods[i].a1].v) {
                    dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a1].v] + goods[i].p + goods[goods[i].a1].p);
                }

                //是主件,买该物品以及附件2
                if (goods[i].a2 != - 1 &&
                        j >= goods[i].v + goods[goods[i].a2].v) {
                    dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a2].v] + goods[i].p + goods[goods[i].a2].p);
                }
                //是主件,买该物品已经两个附件
                if (goods[i].a1 != - 1 && goods[i].a2 != - 1 && j >= goods[i].v + goods[goods[i].a1].v + goods[goods[i].a2].v) {
                    dp[j] = Math.max(dp[j], dp[j - goods[i].v - goods[goods[i].a1].v - goods[goods[i].a2].v] + goods[i].p + goods[goods[i].a1].p + goods[goods[i].a2].p);
                }

            }
        }

        System.out.print(dp[n]);



    }

}
class Good {
    int v;//价格
    int p;//重要度&满意度
    boolean isMain;
    int a1 = -1;//附件1对应索引
    int a2 = -1;//附件2对应索引
}

全部评论

相关推荐

牛客ID:561366855:期望薪资多少?难以相信这简历找不到工作。说明二本电子信息专业想对口就业非常难。
点赞 评论 收藏
分享
喜欢飞来飞去的雪碧在刷代码:可以试一试字节
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务