python找零钱问题_动态规划法(二)找零钱问题
本次博客尝试以storyline的方式来写作,如有不足之处,还请多多包涵~~
问题的诞生
我们故事的主人公叫做丁丁,他是一个十几岁的小男孩,机智聪颖,是某某杂货店的小学徒。在他生活的国度里,只流通面额为1,3,4的硬币。复杂这家店的店长,叫做老王,是个勤奋实干的中年人,每天都要跟钱打交道。
有一天,他心血来潮,叫住正在摆放货物的丁丁,对他说道:“丁丁,你不是学过计算机方面的算法吗?我这里正好有个问题,不知你能解答不?”
一听到算法,丁丁的眼睛里闪出光芒,这正是自己的兴趣所在。于是,他连忙凑到柜台,好奇地问题:“什么问题啊?”
老王也不多说废话,他知道丁丁的聪慧之处,直接了当地说道:“你看啊,每次顾客们买完东西付款后,我们都要找零给他们,我们这边所有的硬币(1,3,4)都是充足的,我想知道一共有多少种找零方式?比如说找零为4的话,就有4=1+1+1+1=3+1=1+3=4共4种方式。”
乍听到这个问题,丁丁有点蒙圈了,因为4的情况是简单的,但是随着找零的面额增加,数量的变化就没有什么规律了。他示意掌柜出去走走,掌柜也欣然同意。
递归?动态规划?
此时我们的主人公正坐在湖边静静地思考,脑海中涌现出各种各样的计算机算法。突然,递归法进入了他的视野,对,就是递归法!他认真地整理着思路:
考虑面额为n的情况,假设n=x1+x2+...+xmn=x1+x2+...+xm.那么,只需考虑最后一个数xm=1,3,4xm=1,3,4的情形。当xm=1,3,4xm=1,3,4,剩下的面额为n−1,n−3,n−4.n−1,n−3,n−4.
假设面额为n的找零方式为f(n)f(n),则f(n)=f(n−1)+f(n−3)+f(n−4)f(n)=f(n−1)+f(n−3)+f(n−4),这样就能按照递归法来做了。
最后,只需要确定初值即可,f(0)=f(1)=f(2)=1,f(3)=2.f(0)=f(1)=f(2)=1,f(3)=2.
问题似乎到这就解决了,因为有了这个递推式,那么,直接定义一个函数就能解决问题了。等等,他想起昨天看到的博客“动态规划法(一)从斐波那契数列谈起”。对了,对于递推式,可以用动态规划法解决啊。于是,他顺手写了一下Python代码:
import time
# calculate the number of ways of integer n can be write the sum of 1,3,4
def sum_part_dp(n):
if n <= 2:
return 1
elif n == 3:
return 2
first = 1
second = 1
third = 1
fourth = 2
# repeat n-3 times
for _ in range(n-3):
answer = first + second + fourth
first = second
second = third
third = fourth
fourth = answer
return fourth
n = 40
t1 = time.time()
s = sum_part_dp(n)
t2 = time.time()
print('面额:%s,方法数:%s,耗时:%s'%(n, s, t2-t1))
他迅速地敲完了以上代码,运行,得到结果:
面额:40,方法数:119814916,耗时:0.0
Bingo,搞定!他满怀欣喜地将这个结果告诉了掌柜老王,老王看了,也禁不住点点头,心想:计算机算法真有用啊!
再一次的挑战
可是老王也是一个有想法的人,他看着丁丁这么干脆利落地解决了这个问题,决心再出一个难题考考他。他清了清喉咙,对丁丁说道:“刚才的问题解答得很棒啊,值得表扬 !但是现在呢,我这又有个麻烦事。每次找零,怎样找零才能使得找零的硬币数最少呢?”
丁丁笑而不语,他点了点头,就抱着他的电脑离开了。老王望着他离去的背影,心想:这个问题要是能解决,以后找零也就省了不少麻烦。不知这次丁丁要用多长时间?
有了上个问题的积累,丁丁对于解决这个问题满怀信心。还是跟刚才的解答方法一样,先用递归,假设面额为nn的找零所用最少硬币数为f(n)f(n),则f(n)=min{f(n−1)+1,f(n−3)+1,f(n−4)+1}.f(n)=min{f(n−1)+1,f(n−3)+1,f(n−4)+1}.采用自底向上的动态规划法,记录每个子问题的解,避免重复求解,这样就能得到f(n)f(n)的值了。那么,怎样才能记录每个子问题的解呢?用Python中的字典啊!这样,硬币数量是得到了,可是具体的找零方式呢?不难,只要用一个变量记录刚才表达式中是取f(n−1)f(n−1)还是f(n−3)f(n−3)还是f(n−4)f(n−4),对应面额为1,3,4,再递归地求解下去即可。
他写下了Python代码:
# 找零钱问题
# 找零钱字典,key为面额,value为最小硬币数
change_dict = {}
# 动态规划法解决问题
# 时间复杂度:多项式时间
# 只求解最小的硬币数量
def rec_change(M, coins):
change_dict[0] = 0
s = 0
for money in range(1, M+1):
num_of_coins = float('inf')
for coin in coins:
if money >= coin:
# 记录每次所用的硬币数量
if change_dict[money-coin]+1 < num_of_coins:
num_of_coins = change_dict[money-coin]+1
s = coin #记录每次找零的面额
change_dict[money] = num_of_coins
return change_dict[M],s
# 求出具体的找零方式
# 用path变量记录每次找零的面额
def method(M, coins):
print('Total denomination is %d.'%M)
nums, path = rec_change(M, coins)
print('The smallest number of coins is %d.'%nums)
print('%s'%path, end='')
while M-path > 0:
M -= path
nums, path = rec_change(M, coins)
print(' -> %s'%path, end='')
print()
coins = (1, 3, 4)
method(50, coins)
运行结果如下:
Total denomination is 50.
The smallest number of coins is 13.
3-> 3-> 4-> 4-> 4-> 4-> 4-> 4-> 4-> 4-> 4-> 4-> 4
几分钟后,当掌柜老王看到这个结果后,惊讶得目瞪口呆!在这家小小的杂货店里,也许藏着一位计算机天才,他这样想到。
而我们的主人公呢?此时,他已经向着斜阳,走在县城的小道上,踌躇满志,准备着去外面的世界看一看~~
注意:本人现已开通两个微信公众号: 用Python做数学(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~
python找零钱问题_动态规划法(二)找零钱问题相关推荐
- python必备单词整理_别乱找了,Python常用单词Word合集,已经给你整理全了
最近我在学python 为大家整理了一下python常用的词汇.在学习python过程中觉得很有趣喔.感兴趣的朋友可以私信我一起研讨. Python (发音:[ 'paiθ(ə)n; (US) 'pa ...
- python数据分析就业前景_数据分析师找工作的秘诀,从读懂招聘 JD 开始
JD(job description缩写),在招聘中,最常用到的意思是岗位介绍和工作职责描述. JD让无数求职者头痛,数据分析师更是其中的头疼之最.这份工作门槛尚可,薪资不错,行业发展前景好,因此吸引 ...
- python顺序结构实验设计_实验二 顺序结构程序设计
实验二 顺序结构程序设计(验证性实验)(二学时) Python 程序设计 实验报告 班级_物流192_________ 姓名_吴陈燕_________ 学号_3190505219__________成 ...
- python小球方案问题_十二个小球称重问题及其Python实现
一.问题描述 在12个外观完全相同的小球中,有一个与其它球重量不同.如何只用一架天平找到这个球并判断它比其它球轻还是重?最少需要称几次?39个球呢? 二.问题分析 这是一个很经典的信息论问题,最开始的 ...
- feignclient对象找不到_为什么我找不到对象呢,一个33岁大龄剩女的疑惑
小木是我朋友,属兔今年33了.不仅我觉的她很优秀,周围的人也觉得她很优秀,但就是现在还单身.下面是她的疑惑. 我各方面条件都还行,为什么找不到对象呢? 性格:温和,善良,阳光,有主见.(对待事物有自己 ...
- python顺序结构实验设计_实验二 顺序结构程序设计(验证性实验)
安徽工程大学 Python程序设计实验报告 班级物流192 姓名 徐敏 学号 3190505232 成绩 _____ 日期 2020.3.22 指导老师 修宇 [实验名称] 实验二 顺序结构程序设计( ...
- python语言基础实验_实验二Python语言基础函数包练习.doc
实验二Python语言基础函数包练习 实验 Python语言基础函数包练习:1208 学号: 实验目的 1.Python语言包,如math.NumPySciPy和Matplotlib等函数包的使用实验 ...
- python解决换零钱问题_多种解法解决“零钱兑换”问题
最近在LeetCode上刷算法题,准备秋招.刷了一些题之后,发现有些题非常棒,能够将多种知识点结合在一起.本文就以"零钱兑换"问题为例,展示同一道题的多种不同解法. 零钱兑换问题 ...
- python大作业代码_大二期末python大作业有效代码不低于5000行是什么水平?
6月30日更新 鉴于题主说老师已经收回对行数的要求,就请大家看过则罢,不要再点赞了(还有收藏的是什么鬼?).本文说的不过是一些投机取巧的伎俩,不值取,不可取. ~~~以下是原文~~~: 一个熟练工程序 ...
最新文章
- VC++ 打开文件夹,保存文件等对话框的调用
- OVS DPDK--Ring端口配置(五)
- ce5e.cn fadian.php,空包网 PHP mysql
- SAP CRM OData模型里的addressable为true的含义
- midi 音符对应表
- 如何在MySQL中设置外键约束以及外键的作用
- LeetCode Week 6:第 51 ~ 55 题
- Black Hat USA 2020 大会主议题大盘点(上)
- 创建了对嵌入的互操作程序集间接引用,无法嵌入互操作类型
- 机器学习:特征选择之RFormula(SparkMLlib中的RFormula)
- PCB小知识(1)-关于打接地孔
- html怎么设置视频不能快进,【浏览器插件】Video Speed Controller – 网页视频倍速、快进、回放功能0.07~16 倍...
- 大容量Flash型AT91系列ARM核微控制器
- 遥感卫星影像数据全色波段和多光谱波段
- TempDB 收缩方法
- PCB电路板布局方法总结
- 国内首个电子政务云平台落地
- 一个整数,个位是4,把4移动到首位,则变为原来4倍,那么这个数是?
- 菜根谭 全文 及译文
- OkHttp实现延时重试
热门文章
- 【从零开始学习计算机网络——计算机网络传输技术】
- 2017年第十五届Esri中国用户大会资料分享
- iReport属性为空时报表显示空白
- LIMS系统平台在第三方检测实验室中的意义
- 近距离参观VR与汽车技术的结合,了解汽车如何使用VR技术
- 数据库概念mongodb使用数据库CLUD操作
- 一口气挑了101个适合程序员玩耍的项目!国庆可以玩的很嗨啦
- Kubernetes:3步排查K8S Deployment故障
- 计算机专业重大和吉大,中国“计算机专业”高校排名,中科大不敌吉大,电子科技无缘前10...
- win10 安装 Linux子系统(WSL)