python换硬币_Python的硬币兑换动态编程实现记录,CoinChange,最少,组合,python,规划

题目为给定不同面值的n种硬币,面值加起来等于一个特定的数m,求最少需要多少枚硬币实现。

这个问题如果使用暴力求解,需要穷举所有可以加起来等m的组合,时间复杂度为O(m^n)。

def coin_27_plus_1(x):

coins = [2,5,7]

len_s = [x//coin for coin in coins]

sum = 0

times = 0

min_times = sys.maxsize

for i in range(len_s[0]+1):

for j in range(len_s[1]+1):

for k in range(len_s[2]+1):

sum = i*coins[0] + j*coins[1] + k*coins[2]

times = i + j + k

if sum == x and times < min_times:

min_times = times

return min_times

使用动态规划,可以将复杂度将为O(m*n)。分析该问题时,将n暂且设为[2,5,7],m设为27.

要使用动态规划,首先需要确定状态:

最后一步:最优策略中使用的最后一枚硬币

,即有多少枚硬币,最后一步的最优策略就有多少种;

将其优化成子问题:使用最好的硬币拼出更小的面值27-

其次确定转移方程:

然后确定初始条件和边界情况:

初始条件:

边界情况:如果n中的所有硬币组合都不能评出x(包括负数),则

最后使用动态规划就是为了在计算下一项时可以直接已经计算的项,如

,此时f[6]已经计算过,此时就不需要重复计算,代码如下:

def coinChange(self, coin_list, tg_num):

"""

:type coins: List[int]

:type amount: int

:rtype: int

"""

# 最大值变量

import sys

max_v = sys.maxsize

# 创建一个数组,保存计算的值

funcs = [None]*(tg_num+1)

# 初始条件

funcs[0] = 0

# 依次从小到大计算

for s_v in range(1,tg_num+1):

funcs[s_v] = max_v

# 实现转移方程

for coin_v in coin_list:

# 设定边界条件

if s_v >= coin_v and funcs[s_v-coin_v] != max_v:

funcs[s_v] = min(funcs[s_v-coin_v]+1,funcs[s_v])

# 如果计算的值仍然是极大值,直接返回-1

if funcs[tg_num] == max_v:return -1

return funcs[tg_num]

动态规划在解决求解极值问题时是一种很有意思的算法,只要按步骤定义好状态、转移方程和边界,就可以一步步完成,谨以此记录。

解决该问题时,动态规划参考了九章算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值