题目描述:
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例2:
输入:coins = [2], amount = 3
输出:-1
示例3:
输入:coins = [1], amount = 0
输出:0
思路1:
深搜,找到所有可能的方案,再取最小的,这里可以适当的剪枝,如从cions[i]最大的开始搜。 时间复杂度O(2^n)。
思路2:
动态规划——dp[i]拼到最少需要的数量
这道题类似与上台阶问题的思路,状态转移方程:
dp[i] = max{ dp[i-cions[j]] } +1, j : 是coins中所有值
即问题相当于倒数,比如示例1中可以是dp[6] + 1(再来一张5元), dp[9] + 1(再来一张2元), dp[10]+1(再来一张1元).
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
# 状态dp是凑成i需要的硬币数量
# 本题的状态定义和状态转移和爬楼梯问题很类似
dp = [amount+1 for i in range(amount+1)]
# 初始值的设置!!!
dp[0] = 0
for m in range(1, amount+1):
for j in range(len(coins)):
if m-coins[j] >= 0:
dp[m] = min(dp[m-coins[j]], dp[m])
dp[m] += 1
if dp[amount] <= amount:
return dp[amount]
else: #拼不出来!!!
return -1
这里需要注意初始值的设置来保证最后返回的结果是正确的,因为有拼不出来的情况。

本文探讨了一种使用动态规划解决经典问题的方法,即如何用最少的硬币凑出给定金额。通过状态转移方程,展示了如何优化算法以在O(n*amount)时间内求解,避免了深度搜索的指数复杂度。实例演示和代码实现有助于理解这个算法在实际场景中的应用。
1217

被折叠的 条评论
为什么被折叠?



