题解 | 购物单(java版)——动态规划

购物单

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

import java.util.Scanner;

/**
 * @author why
 * @date 2023/04/08 09:40
 * @name
 * @level
 **/
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int money = in.nextInt();
        int num = in.nextInt();

        int[][] dp = new int[num + 1][money / 10 + 1]; //money是10的倍数,这样可以减少空间开支
        Good[] goods = new Good[num + 1]; //物品

        //初始化物品
        for (int i = 1; i <= num; i++) {
            int price = in.nextInt() / 10;
            int weight = in.nextInt();
            int id = in.nextInt();
            goods[i] = new Good(price, weight, id);
        }

        //根据物品的id判断是主件还是附件,如果是附件则更新对应的主件的id1和id2
        for (int i = 1; i <= num; i++) {
            int id = goods[i].id;
            if (id > 0) {
                if (goods[id].id1 == -1) {
                    goods[id].id1 = i; //标识附件存在
                } else {
                    goods[id].id2 = i;
                }
            }
        }

        //开始遍历
        for (int i = 1; i <= num; i++) {
            //分三种情况(这里主+附1和主+附2要分开讨论)
            int money1 = 0, money2 = 0, money3 = 0, money4 = 0; //主,主+附1,主+附2,主+附1+附2
            int value1 = 0, value2 = 0, value3 = 0, value4 = 0; //主,主+附1,主+附2,主+附1+附2

            value1 = goods[i].price * goods[i].weight;
            money1 = goods[i].price;
            if (goods[i].id1 != -1) {
                money2 = goods[goods[i].id1].price + money1;
                value2 = value1 + goods[goods[i].id1].price * goods[goods[i].id1].weight;
            }
            if (goods[i].id2 != -1) {

                money3 = goods[goods[i].id2].price + money1;
                value3 = goods[goods[i].id2].price * goods[goods[i].id2].weight + value1;
            }

            if (goods[i].id1 != -1 && goods[i].id2 != -1) {
                money4 = goods[goods[i].id2].price + money2;
                value4 = goods[goods[i].id2].price * goods[goods[i].id2].weight + value2;
            }
            //System.out.println(value1+" "+value2+" "+value3+" "+value4);

            for (int j = 1; j <= (money / 10); j++) {
                if (goods[i].id > 0) {
                    dp[i][j] = dp[i - 1][j]; //不能单独选中附件
                } else {
                    /*
                    不选择当前物品,因为下面要根据j和money的比较来选择不同的主件和附件的组合情况,所以这里先向上继承,下面当j<money/1/2/3/4
                    //的时候就不用另写分支了
                    详见01背包代码模板:
                    for(int i = 1; i < weight.size(); i++) { // 遍历物品
                        for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
                            if (j < weight[i]) dp[i][j] = dp[i - 1][j];
                            else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
                            }
                        }
                    */
                    dp[i][j] = dp[i - 1][j];
                    if (j >= money1) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - money1] + value1); //选中主件
                    }
                    if (j >= money2 && value2 > 0) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - money2] + value2); //选中主件+附件1
                    }
                    if (j >= money3 && value1 > 0) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - money3] + value3); //选中主件+附件2
                    }
                    if (j >= money4 && value4 > 0) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - money4] + value4); //选中主件+附件1+附件2
                    }
                }

            }
        }
        System.out.print(dp[num][money / 10] * 10);
//        for (int i = 1; i <= num; i++) {
//            for (int j = 1; j <= money/10; j++) {
//                System.out.print(dp[i][j] + "  ");
//            }
//            System.out.println();
//        }
    }
}

class Good {
    public int price;
    public int weight;
    public int id;
    public int id1;
    public int id2;

    public Good() {
    }

    ;

    public Good(int p, int w, int i) {
        this.price = p;
        this.weight = w;
        this.id = i;
        this.id1 = -1;
        this.id2 = -1;
    }

}

全部评论

相关推荐

我也曾抱有希望:说的好直白
点赞 评论 收藏
分享
宝宝巴逝:给他一巴掌看他还发不发癫
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务