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

123 阅读4分钟

问题重述

小S需在预算V内租用Q种货船,每种货船有固定数量m、租赁成本v和载货量w,求能租用的最大总载货量。

思路分析

  1. 明确目标

    • 小S的目标是在给定的预算 V 内,租用货船以承载最大的总货物量。
  2. 定义状态

    • 使用动态规划(DP)来解决问题。定义一个数组 dp,其中 dp[j] 表示在预算为 j 时能租用的货船的最大总载货量。
  3. 初始化状态

    • 初始化 dp 数组,所有元素都设为 0。这表示在没有预算时,无法租用任何货船,因此载货量为 0。
  4. 状态转移

    • 遍历每种货船,对于每种货船,再遍历其所有可用的数量。
    • 对于每种货船的每个实例,从预算的最大值 V 开始向前遍历到该货船的租赁成本 v[i](注意要包括 v[i],因此是 range(V, v[i] - 1, -1))。
    • 在遍历过程中,更新 dp[j] 的值。如果租用当前货船,则新的载货量为 dp[j - v[i]] + w[i](即剩余预算下的最大载货量加上当前货船的载货量)。比较这个值与 dp[j] 的原值,取较大者作为新的 dp[j] 值。
  5. 结果输出

    • 遍历完成后,dp[V] 即为在预算 V 下能租用的货船的最大总载货量。
  6. 算法复杂度

    • 时间复杂度:O(Q * m[i] * V),其中 Q 是货船种类数量,m[i] 是第 i 种货船的数量,V 是总预算。因为对于每种货船的每个实例,都需要遍历从 V 到 v[i] 的所有预算值。
    • 空间复杂度:O(V),因为需要使用一个大小为 V+1 的数组来存储动态规划的状态。

代码分析

1.- 函数 solution 接收三个参数:货船种类数量 Q(虽然未在函数内部直接使用,但可以作为输入验证的一部分)、总预算 V 和货船信息列表 ships

  • 初始化一个长度为 V+1 的动态规划数组 dp,用于存储不同预算下的最大载货量。
  • 通过嵌套循环遍历每种货船及其数量,并逆序更新 dp 数组,以确保在计算当前预算下的最大载货量时,已经考虑了所有可能的子问题解。
  • 使用 max 函数比较当前载货量与选择租用当前货船后的新载货量,以更新 dp 数组的值。
  • 最终返回 dp[V],即在总预算 V 下能租用的货船的最大总载货量。
def solution(Q, V, ships):
    # 初始化 dp 数组,长度为 V+1,所有元素初始化为 0
    # dp[j] 表示在预算为 j 时能租用的货船的最大总载货量
    dp = [0] * (V + 1)
    
    # 遍历每种货船的信息 (m, v, w)
    for m, v, w in ships:
        # 对于当前货船,遍历其所有可用的数量 m
        for _ in range(m):
            # 从预算的最大值 V 开始,向前遍历到该货船的租赁成本 v(包含 v)
            # 注意要逆序遍历,以避免重复使用同一艘货船进行多次计算
            for j in range(V, v - 1, -1):
                # 更新 dp[j],表示在预算为 j 时能得到的最大载货量
                # 要么保持原来的值 dp[j],要么选择租用当前货船并加上剩余预算下的最大载货量 dp[j - v] + w
                dp[j] = max(dp[j], dp[j - v] + w)
    
    # 返回在预算 V 下的最大载货量
    return dp[V]

2.- 主程序部分使用 if __name__ == "__main__": 来确保当脚本作为主程序运行时才执行以下代码。

  • 定义了两个测试用例 ships 和 ships2,分别包含不同的货船信息。
  • 对于每个测试用例,调用 solution 函数并传入相应的参数(货船种类数量、总预算和货船信息列表),然后验证返回的结果是否与预期值相等。
  • 使用 print 函数输出结果验证的结果,以便于观察测试是否通过。
if __name__ == "__main__":
    # 定义两个测试用例
    ships = [[2, 3, 2], [3, 2, 10]]  # 第一个测试用例的货船信息
    ships2 = [[30, 141, 47], [9, 258, 12], [81, 149, 13], [91, 236, 6], [27, 163, 74], [34, 13, 58], [61, 162, 1], [80, 238, 29], [36, 264, 28], [36, 250, 2], [70, 214, 31], [39, 116, 39], [83, 287, 4], [61, 269, 94], [23, 187, 46], [78, 33, 29], [46, 151, 2], [71, 249, 1], [67, 76, 85], [72, 239, 17], [61, 256, 49], [48, 216, 73], [39, 49, 74]]  # 第二个测试用例的货船信息
    
    # 调用 solution 函数并验证结果
    print(solution(2, 10, ships) == 32)  # 验证第一个测试用例的结果
    print(solution(23, 400, ships2) == 1740)  # 验证第二个测试用例的结果  

总结

上述代码使用动态规划解决货船租赁问题,计算在给定预算内能租用的货船的最大总载货量,并验证了两个测试用例。