贪心算法
小S的货船租赁冒险
1.题目思路
在这个问题中,我们需要使用一种称为“背包问题”的组合优化方法。多重背包问题是指在给定预算和多种物品(货船)的情况下,每种物品有固定数量的限制,如何选择物品以使得总价值(载货量)最大化的问题。这里的“物品”是货船,它们的“价值”是载货量,而“重量”是租赁成本。
2.详细方法
初始化动态规划数组:创建一个一维数组 dp,长度为 V+1,其中 V 是预算。数组的每个元素 dp[j] 表示在预算不超过 j 的情况下能够达到的最大载货量。初始时,所有元素都设置为0,因为没有任何预算时,载货量为0。
遍历每种货船:对于 ships 列表中的每种货船,我们遍历它的数量 m、租赁价格 v 和载货量 w。
更新动态规划数组:对于每种货船,我们从后向前遍历预算 j,从 V 到 v-1。这样做是为了避免在同一轮迭代中重复使用同一种货船。对于每个预算 j,我们检查是否可以租用当前的货船。如果可以(即 j >= v),我们就尝试将这种货船加入到当前的组合中,并更新 dp[j] 的值。由于每种货船有 m 艘,我们需要在内层循环中重复这个过程 m 次,以确保不超过每种货船的数量限制。
贪心选择:在每一步,我们使用贪心策略,即如果租用当前货船能够增加载货量,我们就选择租用它。具体来说,我们比较不租用当前货船时的载货量(dp[j])和租用一艘当前货船后的载货量(dp[j - v] + w)。我们选择两者中较大的值作为新的 dp[j]。
返回结果:遍历完所有货船和预算后,dp[V] 就是最终的答案,即在预算 V 内能够达到的最大载货量。
3.代码实现
def solution(Q, V, ships):
# 初始化 dp 数组
dp = [0] * (V + 1)
# 遍历每种货船
for m, v, w in ships:
# 遍历每种货船的数量
for _ in range(m):
# 从后往前更新 dp 数组,避免重复计算
for j in range(V, v - 1, -1):
dp[j] = max(dp[j], dp[j - v] + w)
# 返回在预算 V 下的最大载货量
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)