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
思路
这个问题类似0/1背包问题,用动态规划求解。
问题分析:
- 有
Q种货船,每种货船有固定数量m[i]、租赁费用v[i]和载货量w[i]。 - 每种货船最多租用
m[i]艘,租赁价格是v[i]元,载货量是w[i]。 - 给定一个总预算
V,我们需要选择货船组合,使得总的载货量最大,且总的租赁费用不超过V。
我们定义一个 dp[i] 数组,表示在预算为 i 时,能够达到的最大载货量。
转移方程:
-
对于每一种货船类型
i,如果我们要租用该货船类型的k艘(0 <= k <= m[i]),则:- 租用
k艘的费用是k * v[i],载货量是k * w[i]。 - 更新
dp[i]数组:对于预算j,我们可以通过选择不同数量的k艘来更新最大载货量。
- 租用
优化:
由于每种货船可以选择最多 m[i] 艘,我们需要处理每种货船的数量限制。可以通过将每种货船的多重选择转换为多个 0/1 背包问题来处理(每次处理一个货船的数量限制)。
代码实现
def solution(Q, V, ships):
# 初始化 dp 数组,dp[i] 表示预算为 i 时的最大载货量
dp = [0] * (V + 1)
# 遍历每种货船
for m, v, w in ships:
# 对每种货船,使用从后往前的方式更新 dp 数组,避免重复计算
for budget in range(V, -1, -1):
# 考虑租用 k 艘货船(0 <= k <= m)
for k in range(1, m + 1):
cost = k * v
if cost <= budget:
dp[budget] = max(dp[budget], dp[budget - cost] + k * w)
else:
break
return dp[V]
时间复杂度:
对于每种货船,我们需要处理所有的预算 budget,并且每次考虑的数量 k 是从 1 到 m[i]。因此,时间复杂度大约是 O(Q * V * m[i]),其中 Q 是货船种类的数量,V 是预算,m[i] 是第 i 种货船的最大数量。