题解 | #购物单#

购物单

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

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            long s = System.currentTimeMillis();
            String line1 = in.nextLine();
            String[] arr = line1.split(" ");
            int money = Integer.parseInt(arr[0]);
            int count = Integer.parseInt(arr[1]);
            List list = new ArrayList<>();//主件容器
            Map<Integer, List<String[]>> map = new HashMap<>();//副件容器
            while (count > 0) {
                String[] items = in.nextLine().split(" ");
                int type = Integer.parseInt(items[2]);
                if (type > 0) {//保存副件
                    if (!map.containsKey(type)) {
                        map.put(type, new ArrayList<String[]>());
                    }
                    map.get(type).add(items);
                    list.add(null);//占位置
                } else {//保存主件
                    list.add(items);
                }
                count--;
            }
            int v = visit(money, list, map);
            System.out.println(v);
        }
    }
    
    private static int visit(int c, List<String[]> list, Map<Integer, List<String[]>> map) {//动态规划dp
        int n = list.size();

        int[] dp = new int[c + 1];
        for (int i = 0; i < n; i++) {
            if (list.get(i) == null) continue;

            int w = Integer.parseInt(list.get(i)[0]);
            int v = Integer.parseInt(list.get(i)[0]) * Integer.parseInt(list.get(i)[1]);
            for (int j = c; j >= w; j--) {
                dp[j] = Math.max(dp[j], dp[j - w] + v);
                if (map.containsKey(i + 1)) {
                    List<String[]> app = map.get(i + 1);
                    if (app.size() > 0) {//计算第一个副件
                        int w1 = Integer.parseInt(app.get(0)[0]);
                        int v1 = Integer.parseInt(app.get(0)[0]) * Integer.parseInt(app.get(0)[1]);
                        if (j >= w + w1) {//单选副件1
                            dp[j] = Math.max(dp[j], dp[j - w - w1] + v + v1);
                        }
                    }
                    if (app.size() > 1) {//计算第二个副件
                        int w1 = Integer.parseInt(app.get(0)[0]);
                        int v1 = Integer.parseInt(app.get(0)[0]) * Integer.parseInt(app.get(0)[1]);
                        int w2 = Integer.parseInt(app.get(1)[0]);
                        int v2 = Integer.parseInt(app.get(1)[0]) * Integer.parseInt(app.get(1)[1]);
                        if (j >= w + w2) {//单选副件2
                            dp[j] = Math.max(dp[j], dp[j - w - w2] + v + v2);
                        }
                        if (j >= w + w1 + w2) {//副件1+副件2
                            dp[j] = Math.max(dp[j], dp[j - w - w1 - w2] + v + v1 + v2);
                        }
                    }
                }
            }
        }
        return dp[c];
    }

}

全部评论
哎哟,花了两天,终于搞出来了。1、先用动态规划里的压缩滚动。2、然后在主件和副件之间重新更新dp值。副件内容单独存,对应到主件编号上
点赞 回复 分享
发布于 2024-02-20 22:52 重庆

相关推荐

头像
04-17 09:29
已编辑
湖南农业大学 后端
睡姿决定发型丫:本硕末9也是0offer,简历挂了挺多,只有淘天 美团 中兴给了面试机会,淘天二面挂,美团一面kpi面,中兴一面感觉也大概率kpi(虽然国企,但一面0技术纯聊天有点离谱吧)
点赞 评论 收藏
分享
05-07 13:29
已编辑
门头沟学院 Java
北斗导航Compass低仿版:能不能先搞清楚优先级啊,怎么可能是项目问题,项目很重要吗?又没学历 又没实习大厂凭啥约面?那玩具项目 没应用在真实生产环境下的 就算做上天又有什么用?早点找个小公司实习 拿小公司实习去投大厂实习,这才是你现在该做的
投递美团等公司10个岗位 简历被挂麻了,求建议
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务