1 条题解

  • 0
    @ 2023-12-14 11:13:04

    混合背包,看题可以发现能把这个问题转化成01背包+完全背包的结合,代码实现如下

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int M = sc.nextInt(), N =sc.nextInt();
            int[] W = new int[N];//第i种物品的重量W i
            int[] C = new int[N];//第i种物品的价值C i
            int[] nums = new int[N];//第i种物品的数量nums i
            int num = 0;//选择物品的总次数
            for (int i = 0; i < N; i++) {
                //读取数据
                W[i] = sc.nextInt();
                C[i] = sc.nextInt();
                nums[i] = sc.nextInt();
                num += nums[i] == 0 ? 1: nums[i];
            }
            //设计背包   bag[i] 表示选择物品重量和为i时的最大价值
            int[] bag = new int[M+1];
            int di = 0;//表示第 di 种物品
            for(int i = 1; i <= num&&di < N; i++){
                //若数量有限,走01背包;若数量无限,走完全背包。
                if(nums[di] != 0){
                    //01背包思路 逆序更新数据 
                    for (int j = M; j >= 1; j--) {
                        if(j >= W[di]){
                            bag[j] = Math.max(bag[j],bag[j-W[di]] + C[di]);
                        }else bag[j] = Math.max(bag[j],bag[j-1]);
                    }
                    //第 di 种物品的个数清零后 换第 di+1 种物品
                    if(--nums[di] <= 0){
                        di++;
                    }
                }else {
                    //完全背包 正序更新数据
                    for (int j = 1; j <= M; j++) {
                        if(j >= W[di]){
                            bag[j] = Math.max(bag[j],bag[j-W[di]] + C[di]);
                        }else bag[j] = Math.max(bag[j],bag[j-1]);
                    }
                    //换第 di+1 种物品
                    di++;
                }
            }
            //输出容量为M时所取物品的最大价值
            System.out.println(bag[M]);
        }
    }
    
    

    信息

    ID
    575
    时间
    1000ms
    内存
    64MiB
    难度
    8
    标签
    (无)
    递交数
    24
    已通过
    6
    上传者