题解 | #购物单#

购物单

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

/*/
一、思路:1、常规动态规划;
2、将子物品另外存放,不单独dp遍历,在dp遍历到父物品时,将所有子物品在一同父物品遍历。
二、其中有两个子物品的父物品遍历思路如下:
①只购买一个父物品;
②父物品和某一个子物品;
③父物品和另一个子物品;
④父物品和两个子物品;
⑤最后将所有情况比较大小即可。
三、因情况过多,代码可能过长。因此,可以考虑在dp循环中使用continue,更适合本题实际情况,来减少代码复杂度。
/*/

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int all = in.nextInt(), n = in.nextInt();
        int w[] = new int[n], v[] = new int[n], st[] = new int[n];//存储价格、重要度、是否是子物品;
        ArrayList<Integer> list[] = new ArrayList[n];//存储子物品;
        int ans[] = new int[all + 1];//一维滚动数组存储答案;
        for(int sa = 0; sa < n; sa ++) list[sa] = new ArrayList<Integer>();//初始化;
        for(int sa = 0; sa < n; sa ++){
            w[sa] = in.nextInt(); v[sa] = in.nextInt();
            int tim = in.nextInt();
            st[sa] = tim;
            if(tim == 0) continue;
            list[tim - 1].add(sa);
        }//记忆数据;

        for(int sa = 0; sa < n; sa ++){//双重for循环dp;
            for(int wq = all; wq >= 0; wq --){
                if(w[sa] > wq || st[sa] != 0) continue;//筛选掉子物品和超重物品;
                ans[wq] = Math.max(ans[wq], ans[wq - w[sa]] + v[sa] * w[sa]);
                if(list[sa].size() == 0) continue;//筛选掉没有子物品的父物品;
                int ind = list[sa].get(0);
                if(w[sa] + w[ind] <= wq)//筛选掉超重物品,此时不能用continue,防止跳走导致少遍历一种情况
                    ans[wq] = Math.max(ans[wq], ans[wq - w[sa] - w[ind]] + v[sa] * w[sa] + v[ind] * w[ind]);
                if(list[sa].size() == 1) continue;//筛选掉只有一个子物品的父物品;
                int ind2 = list[sa].get(1);
                if(w[sa] + w[ind2] > wq) continue;//继续添加限制条件,筛选掉超重的物品;
                ans[wq] = Math.max(ans[wq], ans[wq - w[sa] - w[ind2]] + v[sa] * w[sa] + v[ind2] * w[ind2]);
                if(w[sa] + w[ind2] + w[ind] > wq) continue;//继续筛选掉超重物品;
                ans[wq] = Math.max(ans[wq], ans[wq - w[sa] - w[ind] - w[ind2]] + v[sa] * w[sa] + v[ind2] * w[ind2] + v[ind] * w[ind]);
            }
        }

        System.out.println(ans[all]);//输出答案。
    }
}

全部评论

相关推荐

牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
爱看电影的杨桃allin春招:我感觉你在炫耀
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务