阿里巴巴笔试-2020.7.27-第二题 藏宝架

本文探讨了一道算法题目,涉及藏宝架上宝物的选取问题。要求在遵循每次只能拿选定层的两端宝物的规则下,选出最大价值的m个宝物。介绍了两种解决方案:一是使用多重背包算法,通过动态规划求解;二是利用大根堆,以O(m * log n)的时间复杂度找到最优解。
摘要由CSDN通过智能技术生成

题目

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

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

输入:(第一行是 n 和 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
(注意,每一层中,给出的宝物的价值不是排好序的)

方法一 多重背包

比较经典的解法是用多重背包。如果不了解这个算法,可以先康康:https://www.kancloud.cn/kancloud/pack/70127

processValues(int[] values) 输入为每一层的k个宝物的价值,返回的是从这一层中,取0个 - k 个宝物时,可获取的最大价值。

主函数中,先读数据,然后调用processValues() 处理每一层的值,存到 goods 矩阵中,最后进行动态规划。

dp[ i ][ j ] 表示从 0 - i层,取了j 个货物时获取的价值。
状态转移方程为:
(假设第 i 层的货物数量为 length;注意下面方程中的 k 只是一个循环变量)

dp[i][j] = max( {
    1 <= k <= min(length, j) | dp[i - 1][j - k] + goods[i][k] } )

这里的 k 其实表示的是在 i 层取了 k 件物品,然后在 (i - 1)层取 ( j - k )件,加起来就是 j 件。

时间复杂度是 O(nmk)

public class bao_wu_7_27_dp {
   

    // 对每层的货物,取 0 到 k 个时的最大价值
    // values 是某层货物的价值
    // 比如,temp[0] 为取0个时的最大价值,temp[2]为取2个时的最大价值
    public static int[] processValues(int[] values) {
   
        int[] temp = new int[values.length + 1];
        temp[0] = 0;
        int i = 0;
        int j = values.length - 1;
        int cur = 1;
        while(cur < temp.length) {
   
            if (values[i] > values[j]) {
   
                temp[cur] = values[i] + temp[cur - 1]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值