[LeetCode] 由 “找零钱" 所想
Ref: [Optimization] Dynamic programming【寻找子问题】
Ref: [Optimization] Advanced Dynamic programming【优于recursion】
显然,本篇是关于”动态规划"的部分。
找零钱
一、简单直白策略
要点:”个数“其实代表了“for循环”的层数。但“个数”不定,使用“递归”反而能解决这个问题,减少思路上的负担。
import time def recMC(coinValueList, change):
minCoins = change
if change in coinValueList:
return 1
else:
for i in [c for c in coinValueList if c <= change]:
# 遍历每一个变量, 相当于多重循环。有意思的是,循环的深度是不确定的;
numCoins = 1 + recMC(coinValueList, change-i)
# 得到这个遍历分支的最终结果;
if numCoins < minCoins:
minCoins = numCoins
return minCoins start = time.time()
print(recMC([1,5,10,25], 63))
end = time.time()
print(end-start)
耗时:31秒。
二、记忆化策略
要点:增加了”结果缓存“,效率极具增加。

代码中的 knownResults 记录了上图中节点(某个change时)的最优/最小的值,作为了记录。
def recDC(coinValueList, change, knownResults):
minCoins = change
if change in coinValueList:
knownResults[change] = 1 # 一个硬币刚刚好
return 1
elif knownResults[change] > 0:
return knownResults[change]
else:
for i in [c for c in coinValueList if c <= change]:
#
numCoins = 1 + recDC(coinValueList, change-i, knownResults)
# 更新minCoins
if numCoins < minCoins:
minCoins = numCoins
knownResults[change] = minCoins return minCoins
def main():
amnt = 2163
print(recDC([1,2,5,10,21,25], amnt, [0]*(amnt+1))) main()
耗时:0.01秒。
三、动态规划策略
要点:不是从上到下的 (递归) 思维,且容易栈溢出;而是从最小的情况入手,逐渐扩大。
def dpMakeChange(coinValueList, change, minCoins, coinsUsed):
# 首先,考虑所有的 "情况",是从小到大考虑
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:
coinCount = minCoins[cents-j] + 1
newCoin = j # 考虑过该 "情况",更新记录
minCoins[cents] = coinCount
coinsUsed[cents] = newCoin return minCoins[change] def printCoins(coinsUsed, change):
coin = change
while coin > 0:
thisCoin = coinsUsed[coin]
print(thisCoin)
coin = coin - thisCoin @fn_timer
def main():
amnt = 2163
clist = [1,2,5,10,21,25]
coinsUsed = [0]*(amnt+1)
coinsCount = [0]*(amnt+1) # print("Making change for", amnt, "requires")
print(dpMakeChange(clist, amnt, coinsCount, coinsUsed), "coins")
# print("They are:")
# printCoins(coinsUsed,amnt)
# print("The used list is as follows:")
# print(coinsUsed) main()
耗时:0.003秒。
End.
[LeetCode] 由 “找零钱" 所想的更多相关文章
- LeetCode之找零钱
题目:已知不同面值的钞票,求如 何用最少数量的钞票组成某个金额,求可 以使用的最少钞票数量.如果任意数量的已知面值钞票都无法组成该金额, 则返回-1. 示例: Input: coins = [1, 2 ...
- PAT-乙级-1037. 在霍格沃茨找零钱(20)
1037. 在霍格沃茨找零钱(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 如果你是哈利·波特迷,你会知 ...
- 贪心算法-找零钱(C#实现)
找零钱这个问题很清楚,无非就是始终拿可以取的最大面值来找,最后就使得张数最小了,这个实现是在假设各种面值足够多的情况下. 首先拖出一个界面来,最下面是一个listbox控件 对应的代码:问题比较简单, ...
- PAT 1037 在霍格沃茨找零钱(20)(代码+思路)
1037 在霍格沃茨找零钱(20)(20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 -- 就如海格告诉哈利的:"十七个银西可(Sickle)兑一个加隆(Galleon) ...
- PAT 乙级 1037 在霍格沃茨找零钱(20)C++版
1037. 在霍格沃茨找零钱(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 如果你是哈利·波特迷,你会知 ...
- 【算法笔记】B1037 在霍格沃茨找零钱
1037 在霍格沃茨找零钱 (20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特( ...
- PAT——乙级1022:D进制的A+B &乙级1037:在霍格沃茨找零钱
1022 D进制的A+B (20 point(s)) 输入两个非负 10 进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数. 输入格式: 输入在一行中依 ...
- 动态规划--找零钱 coin change
来自http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/ 对于整数N,找出N的所有零钱的表示.零钱可以用S={s1,s ...
- PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20)
PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20) http://www.patest.cn/contests/pat-b-practise/1037 ...
随机推荐
- Ubuntu系统开发环境完整搭建
安装搜狗输入法 点击我下载哦 idea快捷键冲突 输入发占用快捷键.撤掉输入法的快捷键.还有系统自带快捷键也要取消. 安装deepin-terminal 在tools工具包中找到deepin-term ...
- 常用Linux备份
用于备份的Tar 备份工具Tar是以前备份文件的可靠方法,几乎可以工作于任何环境中,Linux老用户一般都信赖它. Linux中以.tar结尾的文件都是用tar创建的.它的使用超出了单纯的备份,可用来 ...
- CocosCreator上的游戏(调试)发布到微信小程序
1.下载CocosCreator,微信开发者工具 官网地址:http://www.cocos.com/download 官网下载:https://developers.weixin.qq.com/mi ...
- Codeforces 220C
题意略. 思路: 我们可以把 bi[ i ] 在 ai[ ] 中的位置记录下来,然后算出 i - mp[ bi[i] ] ,再将它压入一个multiset.每次我们就二分地来寻找离0最近的数字来作为答 ...
- ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名
ABP默认的MVC启动模板在登录后, 右上角显示的是用户名: 如果想让它显示用户的姓名该如何做呢?这就需要用到ABP一个非常强大的功能------虚拟文件系统. 前期准备 使用ABP CLI创建一个名 ...
- Requests方法 -- 参数关联与JSESSION(上一个接口的返回数据作为下一个接口的请求参数)
前言 参数关联是接口测试和性能测试最为重要的一个步骤,很多接口的请求参数是动态的,并且需要从上一个接口的返回值里面取出来,一般只能用一次就失效了.最常见的案例就是网站的登录案例,很多网站的登录并不仅仅 ...
- 【Linux命令】nohup命令
nohup命令 不挂断的运行,它会使您的脚本被忽略SIGHUP,并重定向stdout/stderr到一个文件nohup.out,以便在您注销后该命令可以在后台继续运行. 1)语法 nohup Comm ...
- P2059 [JLOI2013]卡牌游戏 概率DP
link:https://www.luogu.org/problemnew/show/P2059 题意: 有n个人,类似约瑟夫环的形式踢人,但是报的数是不同的,是在给定的许多数中随机抽取,问最后第i个 ...
- cogs2823求组合数(lucas定理
http://cogs.pro:8080/cogs/problem/problem.php?pid=vNQJJVUVj 再写个数学水题,其实lucas适用于m,n比较大而p比较小的情况. 题意:给出两 ...
- CodeForces 804C Ice cream coloring
Ice cream coloring 题解: 这个题目中最关键的一句话是, 把任意一种类型的冰激凌所在的所有节点拿下来之后,这些节点是一个连通图(树). 所以就不会存在多个set+起来之后是一个新的完 ...