考虑到涉及子问题重叠
即,达到当前金额的最优方法与达到(当前金额-每一个小于当前金额的硬币面值)的最优方法相关
使用动态规划的方法。
dp[i]为凑出i的最少硬币数量方法
则dp[i] = min(dp[i-coins[1]],dp[i-coins[2]],…,dp[i-coins[j]])
其中coins是升序的list,coins[j]是面值小于i的最大面值硬币
class Solution:
def __init__(self):
self.adict = {0:0}
def coinChange(self, coins: List[int], amount: int) -> int:
types = len(coins)
if coins == []:
return -1
elif types == 1:
if amount % coins[0] == 0:
return int(amount / coins[0])
else:
return -1
for i in range(1,amount+1):#value in coins:
if i in coins:
self.adict[i] = 1
else:
self.adict[i] = -1
for i in range(1,amount+1):#对每一种可能的钱数
if i not in coins:#对非正好硬币面值的数字
for j in coins:#对每一种面值的硬币
if i >= j and self.adict[i-j] != -1:#若当前数字>=当前面值 且 当前数字-当前面值后 可以达到
if self.adict[i] == -1 or self.adict[i] > (1+self.adict[i-j]) :#若此时 这个数字还是不可达到 或者 出现更优解法
self.adict[i] = (1+self.adict[i-j])
print(i,self.adict[i])
#self.coins = sorted(coins)#coins
#print(self.coins)
return self.adict[amount]#int(self.dp(amount))