小s的货船租赁冒险 | 豆包MarsCode AI刷题

63 阅读4分钟

问题描述

小S在码头租用货船,有 Q 种不同类型的货船可供选择。每种货船有固定的数量 m[i]、租赁成本 v[i] 和最大载货量 w[i]。小S希望在预算 V 元内,租用能够承载最大总货物的货船组合。每种货船的具体信息包括数量、租赁价格和载货量。小S需要你帮忙计算在给定预算下,她能租用的货船的最大总载货量是多少。

  • Q: 货船的种类数量。
  • V: 李华可用的总预算(单位:元)。
  • ships: 一个列表,其中每个元素是一个元组 [m[i], v[i], w[i]],分别表示第 i 种货船的数量、租赁价格和每艘货船的最大载货量。

测试样例

样例1:

输入:Q = 2,V = 10,ships = [[2, 3, 2], [3, 2, 10]]
输出:32

样例2:

输入:Q = 3,V = 50,ships = [[5, 10, 20], [2, 20, 30], [3, 15, 25]]
输出:100

样例3:

输入:Q = 1,V = 100,ships = [[10, 5, 50]]
输出:500

样例4:

输入:Q = 4,V = 100,ships = [[1, 100, 200], [2, 50, 100], [3, 33, 66], [4, 25, 50]]
输出:200

样例5:

输入:Q = 2,V = 300,ships = [[100, 1, 1], [50, 5, 10]]
输出:550

问题建模

1. 输入数据

• Q:货船种类数量。

• V:预算(元)。

• ships:一个包含所有货船信息的列表,其中每个元素为 [m[i], v[i], w[i]],分别表示第 i 种货船的数量、租赁价格和最大载货量。

2. 输出结果

目标是在预算不超过 V 元的条件下,选择货船的组合,使总载货量达到最大。

3. 约束条件

• 每种货船的租用数量不能超过其提供的总量 m[i]。

• 总费用不能超过预算 V。

4. 背包问题抽象

这是一个典型的多重背包问题,每种货船提供一定数量的物品,每个物品有重量(租赁成本)和价值(载货量)。求解如何在总重量受限的条件下,使价值最大化。

解题思路

我们用**动态规划(Dynamic Programming, DP)**来解决这个问题。

1. DP 状态定义

定义 dp[j] 为在预算为 j 元的情况下,能够承载的最大总货物量。

2. 转移方程

对于每种货船 [m[i], v[i], w[i]]:

• 如果选择租用 k 艘(其中  0 \leq k \leq m[i] ):

• 租用的费用为 k * v[i]。

• 增加的载货量为 k * w[i]。

• 更新状态:dp[j] = max(dp[j], dp[j - k * v[i]] + k * w[i]),前提是 j - k * v[i] >= 0。

3. 初始化

• dp[0] = 0,表示预算为 0 时总载货量为 0。

• 其余 dp[j] 初始化为 0。

4. 最终结果

最后的答案是 dp[V],即在预算 V 元时,能够承载的最大总货物量。

def max_cargo(Q, V, ships):
    # 初始化 dp 数组,长度为预算 V+1
    dp = [0] * (V + 1)
    
    # 遍历每种货船类型
    for m, v, w in ships:
        # 多重背包处理
        for j in range(V, -1, -1):  # 从高到低遍历预算
            for k in range(1, m + 1):  # 租用 0 到 m 艘货船
                if j >= k * v:
                    dp[j] = max(dp[j], dp[j - k * v] + k * w)
    
    return dp[V]

# 测试样例
Q = 3
V = 10
ships = [
    [3, 2, 4],  # 3 艘货船,每艘价格 2 元,载货量 4
    [2, 3, 5],  # 2 艘货船,每艘价格 3 元,载货量 5
    [1, 5, 6]   # 1 艘货船,每艘价格 5 元,载货量 6
]

print(max_cargo(Q, V, ships))  # 输出:14

示例讲解

输入数据

• Q = 3:货船种类数量为 3。

• V = 10:总预算为 10 元。

• ships:

• [3, 2, 4]:最多租 3 艘,每艘租赁价格 2 元,载货量 4。

• [2, 3, 5]:最多租 2 艘,每艘租赁价格 3 元,载货量 5。

• [1, 5, 6]:最多租 1 艘,每艘租赁价格 5 元,载货量 6。

解题过程

  1. 初始化 dp 数组:

dp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]。

  1. 处理第一种货船 [3, 2, 4]:

• 租用 1 艘:dp[2] = max(dp[2], dp[0] + 4) = 4。

• 租用 2 艘:dp[4] = max(dp[4], dp[0] + 8) = 8。

• 租用 3 艘:dp[6] = max(dp[6], dp[0] + 12) = 12。

更新后:dp = [0, 0, 4, 0, 8, 0, 12, 0, 0, 0, 0]。

  1. 处理第二种货船 [2, 3, 5]:

• 租用 1 艘:dp[5] = max(dp[5], dp[2] + 5) = 9。

• 租用 2 艘:dp[8] = max(dp[8], dp[2] + 10) = 14。

更新后:dp = [0, 0, 4, 0, 8, 9, 12, 0, 14, 0, 0]。

  1. 处理第三种货船 [1, 5, 6]:

• 租用 1 艘:dp[10] = max(dp[10], dp[5] + 6) = 14。

最终:dp = [0, 0, 4, 0, 8, 9, 12, 0, 14, 0, 14]。

最优解

在预算 10 元下,最多可以承载的货物量为 14。

优化方向

1. 二进制优化

当货船数量 m[i] 很大时,可以用二进制分组优化,将复杂度从  O(Q \cdot V \cdot m[i])  降低到  O(Q \cdot V \cdot \log m[i]) 。

2. 贪心与 DP 结合

当货船租赁价格 v[i] 和载货量 w[i] 成正比时,可以优先选择性价比高的货船,减少 DP 的计算范围。