返回
Python轻松搞定leetcode 2218:从一堆硬币中获取最大价值
后端
2023-09-04 06:42:17
周赛第 286 场的第四题,难度 Hard,以「从一堆硬币中获取最大价值」为题,考察了动态规划和前缀和的思想。题目将实际场景与算法相结合,非常有趣。
首先,我们来看一下题目的具体内容:
给你一个下标从 0 开始的整数数组 piles,其中 piles[i] 表示第 i 堆硬币的数目。你可以从任意一堆硬币中取走任意数目的硬币,也可以不取。
每次操作时,你只能从当前正在考虑的堆中取走硬币。
你需要将取走硬币的操作序列以列表的形式返回。当且仅当你能够取走所有硬币时,才返回列表。如果有多种方法可以取走所有硬币,返回其中任意一种即可。
让我们从一个简单的例子开始, piles = [4, 3, 2, 1, 1]。
我们可以先从第一堆(下标为 0)取走 2 个硬币,然后从第二堆(下标为 1)取走 2 个硬币,再从第三堆(下标为 2)取走 1 个硬币,最后从第四堆(下标为 3)和第五堆(下标为 4)各取走 1 个硬币。这样,我们就取走了所有硬币,并返回取走硬币的操作序列 [2, 2, 1, 1, 1]。
现在,让我们来看看如何使用Python来解决这道难题:
def maxValueOfCoins(piles, k):
"""
:type piles: List[int]
:type k: int
:rtype: List[int]
"""
# 计算前缀和
prefix_sum = [0]
for pile in piles:
prefix_sum.append(prefix_sum[-1] + pile)
# 初始化dp数组
dp = [[-1] * (k + 1) for _ in range(len(piles) + 1)]
# 填充dp数组
for i in range(1, len(piles) + 1):
for j in range(1, k + 1):
for x in range(1, min(i, j) + 1):
dp[i][j] = max(dp[i][j], dp[i - x][j - x] + prefix_sum[i] - prefix_sum[i - x])
# 构建取硬币操作序列
res = []
i, j = len(piles), k
while i > 0 and j > 0:
for x in range(1, min(i, j) + 1):
if dp[i][j] == dp[i - x][j - x] + prefix_sum[i] - prefix_sum[i - x]:
res.append(x)
i -= x
j -= x
break
return res
这段Python代码首先计算前缀和,然后初始化dp数组。之后,它使用循环填充dp数组,记录取走不同数量的硬币时所能获得的最大价值。最后,它构建取硬币操作序列,并返回。
使用上面的代码,我们可以轻松解决leetcode 2218:从一堆硬币中获取最大价值这道难题。赶快尝试一下吧!