AI刷题83:小S的货船租赁冒险题目解析 | 豆包MarsCode AI刷题

45 阅读4分钟

问题描述:83-小S的货船租赁冒险

小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


该题为典型的背包问题的变种,需要使用动态规划。

问题分析

  • 这是一个有限制条件的最优化问题
  • 限制条件:总预算V和每种货船的数量限制m[i]
  • 目标:在预算内获得最大的总载货量
  • 每种货船有三个属性:数量、价格和载货量

解题方法选择

  • 由于这是一个"选择多个物品求最大值"的问题,适合使用动态规划
  • 这是一个完全背包问题的变种,因为每种货船可以选择多次(在数量限制内)
  • 需要考虑每种货船的数量限制,所以要在完全背包的基础上加入数量维度

动态规划设计

# 状态定义
dp[j] 表示预算为j时能获得的最大载货量

# 状态转移方程
dp[j] = max(dp[j], dp[j - k*v] + k*w)
# 其中k是选择的当前类型货船的数量,范围是[1,m]

代码实现步骤

第一步:创建dp数组

dp = [0] * (V + 1)  # 初始化dp数组,大小为预算+1

第二步:遍历每种货船

for i in range(Q):
    m, v, w = ships[i]  # 获取当前货船的数量、价格和载货量

第三步:对每种货船进行动态规划

# 从大到小遍历预算
for j in range(V, -1, -1):
    # 尝试使用不同数量的当前类型货船
    for k in range(1, m + 1):
        if j >= k * v:  # 确保预算足够
            dp[j] = max(dp[j], dp[j - k * v] + k * w)

代码优化考虑

  • 使用逆序遍历预算可以避免重复计算
  • 通过判断预算是否足够(j >= k * v)来减少不必要的计算
  • 直接在原始dp数组上更新,节省空间复杂度

时间复杂度分析

  • 三重循环:O(Q * V * max(m))
  • Q是货船种类数
  • V是总预算
  • max(m)是单种货船的最大数量

完整代码

def solution(Q, V, ships):
    # 创建dp数组,dp[v]表示预算为v时能获得的最大载货量
    dp = [0] * (V + 1)
    
    # 对每种船进行遍历
    for i in range(Q):
        m, v, w = ships[i]  # m:数量 v:价格 w:载货量
        
        # 从大到小遍历预算
        for j in range(V, -1, -1):
            # 对当前类型的船,尝试使用不同数量
            for k in range(1, m + 1):
                # 如果当前预算能够购买k艘这种船
                if j >= k * v:
                    dp[j] = max(dp[j], dp[j - k * v] + k * w)
    
    return dp[V]

if __name__ == "__main__":
    #  You can add more test cases here
    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]]
    print(solution(2, 10, ships) == 32)
    print(solution(23, 400, ships2) == 1740)