2218.从栈中取出K个硬币的最大面值和
dp, https://leetcode.cn/problems/maximum-value-of-k-coins-from-piles/
一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。
每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。
给你一个列表 piles ,其中 piles[i] 是一个整数数组,分别表示第 i 个栈里 从顶到底 的硬币面值。同时给你一个正整数 k ,请你返回在 恰好 进行 k 次操作的前提下,你钱包里硬币面值之和 最大为多少 。
示例 1:

输入:piles = [[1,100,3],[7,8,9]], k = 2
输出:101
解释:
上图展示了几种选择 k 个硬币的不同方法。
我们可以得到的最大面值为 101 。示例 2:
输入:piles = [[100],[100],[100],[100],[100],[100],[1,1,1,1,1,1,700]], k = 7
输出:706
解释:
如果我们所有硬币都从最后一个栈中取,可以得到最大面值和。提示:
n == piles.length1 <= n <= 10001 <= piles[i][j] <= 1051 <= k <= sum(piles[i].length) <= 2000
python
from typing import List
class Solution:
def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int:
n = len(piles)
dp = [[0] * (k + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(k + 1):
current_sum = 0
for x in range(min(j, len(piles[i-1])) + 1):
if x > 0:
current_sum += piles[i-1][x-1]
dp[i][j] = max(dp[i][j], dp[i-1][j-x] + current_sum)
return dp[n][k]
if __name__ == '__main__':
sol = Solution()
piles = [[1, 100, 3], [7, 8, 9]]
k = 2
print(sol.maxValueOfCoins(piles, k)) # Output: 101
piles = [[100], [100], [100], [100], [100], [100], [1, 1, 1, 1, 1, 1, 700]]
k = 7
print(sol.maxValueOfCoins(piles, k)) # Output: 706这是一个典型的动态规划问题,涉及从多个堆中取出硬币的最大价值。题目大意是:给定若干个堆,每个堆包含一些硬币。你需要从每个堆中选择若干个硬币,使得总共选出的硬币数不超过
k,并且硬币的总价值最大。piles是一个二维数组,每个子数组代表一个堆的硬币;k是最多可以选择的硬币数量。
初始化:
pythonn = len(piles) dp = [[0] * (k + 1) for _ in range(n + 1)]
n是堆的数量。dp[i][j]代表考虑前i个堆,最多取j个硬币时的最大价值。初始化时,所有的dp[i][j]都是0,表示初始状态下没有选择任何硬币。填充动态规划表格:
pythonfor i in range(1, n + 1): for j in range(k + 1): current_sum = 0 for x in range(min(j, len(piles[i-1])) + 1): if x > 0: current_sum += piles[i-1][x-1] dp[i][j] = max(dp[i][j], dp[i-1][j-x] + current_sum)这三层嵌套循环的作用是逐步计算每个
dp[i][j]的值:
- 外层循环
i从1到n,表示正在考虑第i个堆。- 中层循环
j从0到k,表示选择的硬币数量。- 内层循环
x从0到min(j, len(piles[i-1])),表示从当前堆中选择的硬币数量。min(j, len(piles[i-1]))保证不会选择超过当前堆硬币数的硬币。
current_sum记录当前堆选择的硬币的总价值。如果x > 0,说明选择了x个硬币,那么就将piles[i-1][x-1]加入到current_sum中。
dp[i][j]的值通过比较两种情况来更新:
- 不选择当前堆的硬币,
dp[i-1][j];- 选择
x个硬币时的值,dp[i-1][j-x] + current_sum。