阿里笔试7.27第二题多重背包解法

题干

有个藏宝架有n层,每层的宝物数量不一,每个宝物都有其价值,现在要求拿出m个宝物,并且需要遵守规则:

  1. 每次只能拿选定层的两端的宝物
  2. 要拿出的m个宝物的总价值是各种方案里最大的

输入:
n m
下面每行代表每层,且第一个数是这层宝物的数量k,后面的则是k个宝物的价值
4 1 2 4 5
5 1 2 4 5 5
样例:
2 3
2 3 2
4 1 4 1 5
输出:5+3+2=10

想了挺久,如有不足,希望各位大佬指正!

多重背包思路:

先用滑动窗口写一个函数getGoods遍历每一层物品,求出从该层取1 to n个物品可获得的最大价值。然后用多重背包的思路,其实就是将每层货架想象为一个物品,但取不同数量的物品价值是已经算好的。

代码

import java.util.Scanner;

public class T27_2 {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        int n_layer = sc.nextInt();
        int V = sc.nextInt();
        int[][] goods = new int[n_layer][];
        for (int i = 0; i < n_layer; i++){
            int n = sc.nextInt();
            int[] arr = new int[n];
            for(int j = 0; j < n; j++){
                arr[j] = sc.nextInt();
            }
            goods[i] = getGoods(arr);
        }
        int[] dp = new int[V+1];
        // muti-package
        for(int i = 0; i < n_layer; i++){
            for(int j = V; j >= 0; j--){
                for (int k = 0; k < goods[i].length && k <= j; k++){
                    dp[j] = Math.max(dp[j], dp[j - k] + goods[i][k]);
                }
            }
        }
        System.out.println(dp[V]);
    }

    private static int[] getGoods(int[] arr) {
        int sum = 0;
        int n = arr.length;
        for(int e : arr) sum += e;
        int[] res = new int[n + 1];
        res[n] = sum;
        for(int i = n-1; i > 0; i--){
            // i 表示从arr中选出i个物品
            // 用滑动窗口从中间删去不选的元素
            int start = 0;
            int end = n - i;
            int min = Integer.MAX_VALUE;
            while(end <= n){
                int tmp = 0;
                for(int j = start; j < end; j++){
                    tmp += arr[j];
                }
                min = Math.min(min, tmp);
                start++;
                end++;
            }
            res[i] = sum - min;
        }
        return res;

    }
}
#笔试题目##阿里巴巴#
全部评论
滑动窗口既然是连续的话,就没必要每次都求和了吧,直接减去头元素,拼接窗口后一个元素这样,能减少一层循环
点赞 回复 分享
发布于 2020-07-31 11:46

相关推荐

10-11 15:42
皖西学院 Java
青鱼LINK:我硕士,也是java0面试,吾道不孤
点赞 评论 收藏
分享
10-30 23:23
已编辑
中山大学 Web前端
去B座二楼砸水泥地:这无论是个人素质还是专业素质都👇拉满了吧
点赞 评论 收藏
分享
评论
4
15
分享
牛客网
牛客企业服务