python实现找零钱_找零钱的最优步骤 探究(python)

问题描述

你是一家超市的收银员,如果客人买了37元的东西,并且给了你100元,请问如何才能找到 给客人数量最少零钱,

如现有1,2,5,10,21,25 这些种类的零钱,最优的是,21,21,21 数量为3 .

思路解析

递归操作:每一次寻找可以用一张纸币去找零,如果不能够找零,则 找到所有<=该值的纸币,减去该纸币的值,再进行递归。

import time

#递归

def rec(coinValueList,change):

minCoins=change

if change in coinValueList:

return 1

else:

for i in [c for c in coinValueList if c <=change]:

numCoins =1 + rec(coinValueList,change-i)

if numCoins

minCoins=numCoins

return minCoins

t0=time.time()

x=rec([1,5,10,25,22],63)

print(x)

t1=time.time()

print("time:",t1-t0)

result:

889d153090ba

image.png

从运行结果来看,这个递归耗时较长,因为做了过多的重复运算

2改进 使用 一个列表来存储 每一个值的最小数量的状态。

import time

def rec_ch(coinValueList,change,knownResult):

minCoins=change

if change in coinValueList:

knownResult[change]=1 #存储状态

return 1

elif knownResult[change]>0:

return knownResult[change]

else:

for i in [c for c in coinValueList if c <=change]:

numCoins =1 + rec_ch(coinValueList,change-i,knownResult)

if numCoins

minCoins=numCoins

knownResult[change]=minCoins

return minCoins

t0=time.time()

list1=[0]*64

y=rec_ch([1,5,10,25,22],63,list1)

print(y)

print(list1)

t1=time.time()

print("time:",t1-t0)

result:

889d153090ba

image.png

3 动态规划 ,我们把2步骤的方法整理一下。

def dp(coinValueList,change,minCoins,coinUsed):

for cents in range(change+1):

coinCount=cents

newCoin = 1

for j in [c for c in coinValueList if c <=cents]:

if minCoins[cents-j]+1

coinCount=minCoins[cents-j]+1

newCoin=j

minCoins[cents]=coinCount

coinUsed[cents]=newCoin

return minCoins[change]

def printCoins(coinUsed,change):

coin=change

while coin>0:

thisCoin=coinUsed[coin]

print(thisCoin)

coin=coin- thisCoin

t0=time.time()

list1=[0]*64

coinUsed=[0]*64

y=dp([1,5,10,25,22],63,list1,coinUsed)

print(y)

#print(list1)

t1=time.time()

print("time:",t1-t0)

printCoins(coinUsed,63)

result:

889d153090ba

image.png

参考:Python数据结构与算法分析 (布拉德利 • 米勒 戴维 • 拉努姆)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值