python找零钱_Python递归 - 找零钱

特殊的方法-循环:

#无法解决某些情况,例如存在21元的零钱

def fun(n):

count = 0

while n > 25:

n = n - 25

count = count + 1

while n > 10:

n = n - 10

count = count + 1

while n > 5:

n = n - 10

count = count + 1

while n > 0:

n = n - 1

count = count + 1

return count

print(fun(63))

特殊的方法 - 递归:

def fun(n): # 分好类

if n <= 0:

return 0

elif n >= 25:

return 1 + fun(n-25)

elif n >= 10:

return 1 + fun(n-10)

elif n >= 5:

return 1 + fun(n-5)

elif n >= 1:

return 1 + fun(n-1)

print(fun(25))

递归 + 记忆:

import time

def recMD(valueList, change, Knowlist):

minNum = change

if change in valueList: # 可以作为结束条件

Knowlist[change] = 1

return 1

elif Knowlist[change] > 0: # 回忆

return Knowlist[change]

else:

for i in [c for c in valueList if c <= change]: # 常用

num = 1 + recMD(valueList, change - i, Knowlist)

if num < minNum:

minNum = num

Knowlist[change] = minNum

return minNum # 最后记得要返回

print(time.process_time()) # time.clock()被抛弃

print(recMD([1, 5, 10, 25], 77, [0]*79)) # 创建全为0的表

print(time.process_time())

递归 + 记忆 + 输出过程:

import time

from pythonds.basic.stack import Stack

def dp(valueList, change, minNum, coinUsed): # minNum初始化为0,之后需要利用到这些数据

for cents in range(1, change+1): # 从小到大递推

coinCount = cents # 初始化一个无害的最小值

newCoin = 1

for j in [c for c in valueList if c <= cents]: # 常用技巧

if 1 + minNum[cents-j] < coinCount:

coinCount = 1 + minNum[cents - j]

newCoin = j

minNum[cents] = coinCount

coinUsed[cents] = newCoin # 每一个change的最优解都是由两部分组成,这里是记录其中一部分

return minNum[change]

def printSelection(change, coinused):

coin = change

s = Stack()

while coin > 0:

thisCoin = coinused[coin]

s.push(thisCoin)

coin = coin - thisCoin

while not s.isEmpty():

print(s.pop())

valList = [1, 5, 10, 25]

amnt = 63

minN = [0]*64

coinUsed = [0]*64

print(dp(valList, amnt, minN, coinUsed)) # 创建表的方式get

print(coinUsed[1:]) # 打印全部

printSelection(amnt, coinUsed) # 打印组成部分

备注:

动态规划解法的必要条件:问题的最有解包含了更小规模的最优解,即每一步都要依靠前面某步的最优解

Talk is cheap. Show me the code. 将算法思路转化成具体代码需要不断实践,积累经验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值