问题描述
小S在码头租用货船,有 QQQ 种不同类型的货船可供选择。每种货船有固定的数量 m[i]m[i]m[i]、租赁成本 v[i]v[i]v[i] 和最大载货量 w[i]w[i]w[i]。小S希望在预算 VVV 元内,租用能够承载最大总货物的货船组合。每种货船的具体信息包括数量、租赁价格和载货量。请帮助小S计算在给定预算下,她能租用的货船的最大总载货量是多少。
输入描述
- Q: 货船的种类数量。
- V: 可用的总预算(单位:元)。
- ships: 一个列表,其中每个元素是一个元组 [m[i],v[i],w[i]][m[i], v[i], w[i]][m[i],v[i],w[i]],分别表示第 iii 种货船的数量、租赁价格和每艘货船的最大载货量。
输出描述
返回在预算 VVV 内能够承载的最大总货物量。
问题分析
这是一个典型的多重背包问题。我们需要在预算 VVV 的限制下,从 QQQ 类货船中选择,尽可能使总载货量最大化。每种货船有数量限制、租赁成本和载货量。
关键点
- 多重背包问题:每种货船有一定数量限制,可以选择多个同类型的货船,但不能超过该数量。
- 最大化载货量:在预算限制下,选择货船组合使得总载货量最大。
- 优化方法:使用二进制拆分将多重背包问题转化为0-1背包问题,降低时间复杂度。
约束条件
- 货船种类数量 Q 可能较大。
- 每种货船的数量 m[i] 可能较大,直接处理会导致时间复杂度过高。
- 需要在预算 V 内选择货船组合。
解法实现
思路
- 动态规划(DP) :使用一维DP数组
dp[v]表示在预算为 vvv 元时能够达到的最大载货量。 - 二进制拆分:将每种货船的数量 m[i]m[i]m[i] 拆分为多个子问题,每个子问题对应 2k2^k2k 个货船,直到总数达到 m[i]m[i]m[i]。
- 状态转移:对于每个拆分后的子货船,遍历预算,从高到低更新
dp[v]。
def solution(Q, V, ships):
dp = [0] * (V + 1)
for ship_index in range(Q):
m, cost, capacity = ships[ship_index]
# 二进制拆分,将 m 个物品拆分成 log(m) 个物品
k = 1
while m > 0:
count = min(k, m) # 本次选取的数量
m -= count
total_cost = count * cost
total_capacity = count * capacity
#从高到低遍历,防止重复计算
for v in range(V, total_cost - 1, -1):
if dp[v - total_cost] + total_capacity > dp[v]:
dp[v] = dp[v - total_cost] + total_capacity
k <<= 1 # k *= 2
return dp[V]
核心逻辑
-
动态规划数组
dp初始化:dp[v]表示在预算为v元时,能够达到的最大总载货量。- 初始时,所有
dp[v]都设为0,因为未选择任何货船时载货量为0。
-
二进制拆分优化:
- 对于每种货船,数量
m[i]可能较大。为了高效处理,可以将其拆分为若干个数量为2^k的子问题。 - 例如,
m = 5可以拆分为1, 2, 2。 - 这种方法将时间复杂度从 O(m)O(m)O(m) 降低到 O(logm)O(\log m)O(logm)。
- 对于每种货船,数量
-
动态规划状态转移:
- 对于每一个拆分后的子货船,遍历预算
v从高到低,尝试更新dp[v]。 - 更新规则为:
dp[v] = max(dp[v], dp[v - total_cost] + total_capacity),其中total_cost和total_capacity分别是当前拆分子货船的总租赁成本和总载货量。
- 对于每一个拆分后的子货船,遍历预算
-
最终结果:
- 遍历完所有货船后,
dp[V]即为在预算V内能够达到的最大总载货量。
- 遍历完所有货船后,
时间复杂度
- 拆分阶段:对于每种货船,最多拆分为 O(logm[i])O(\log m[i])O(logm[i]) 个子问题。
- 动态规划阶段:每个子问题需要遍历预算
V,时间复杂度为 O(V)O(V)O(V)。 - 总时间复杂度:O(Q⋅logm⋅V)O(Q \cdot \log m \cdot V)O(Q⋅logm⋅V),其中
m是每种货船的最大数量。
空间复杂度
- 主要由动态规划数组
dp决定,空间复杂度为 O(V)O(V)O(V)。
结论
通过将多重背包问题转化为多个0-1背包问题,并利用二进制拆分优化,能够有效地在较低的时间复杂度下求解。在预算有限的情况下,选择最优的货船组合以最大化载货量是一种常见的资源分配问题,适用于物流、运输等多个领域。