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] 由 “找零钱" 所想的更多相关文章

  1. LeetCode之找零钱

    题目:已知不同面值的钞票,求如 何用最少数量的钞票组成某个金额,求可 以使用的最少钞票数量.如果任意数量的已知面值钞票都无法组成该金额, 则返回-1. 示例: Input: coins = [1, 2 ...

  2. PAT-乙级-1037. 在霍格沃茨找零钱(20)

    1037. 在霍格沃茨找零钱(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 如果你是哈利·波特迷,你会知 ...

  3. 贪心算法-找零钱(C#实现)

    找零钱这个问题很清楚,无非就是始终拿可以取的最大面值来找,最后就使得张数最小了,这个实现是在假设各种面值足够多的情况下. 首先拖出一个界面来,最下面是一个listbox控件 对应的代码:问题比较简单, ...

  4. PAT 1037 在霍格沃茨找零钱(20)(代码+思路)

    1037 在霍格沃茨找零钱(20)(20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 -- 就如海格告诉哈利的:"十七个银西可(Sickle)兑一个加隆(Galleon) ...

  5. PAT 乙级 1037 在霍格沃茨找零钱(20)C++版

    1037. 在霍格沃茨找零钱(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 如果你是哈利·波特迷,你会知 ...

  6. 【算法笔记】B1037 在霍格沃茨找零钱

    1037 在霍格沃茨找零钱 (20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特( ...

  7. PAT——乙级1022:D进制的A+B &乙级1037:在霍格沃茨找零钱

    1022 D进制的A+B (20 point(s)) 输入两个非负 10 进制整数 A 和 B (≤2​30​​−1),输出 A+B 的 D (1<D≤10)进制数. 输入格式: 输入在一行中依 ...

  8. 动态规划--找零钱 coin change

    来自http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/ 对于整数N,找出N的所有零钱的表示.零钱可以用S={s1,s ...

  9. PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20)

    PAT (Basic Level) Practise (中文)-1037. 在霍格沃茨找零钱(20) http://www.patest.cn/contests/pat-b-practise/1037 ...

随机推荐

  1. Ubuntu系统开发环境完整搭建

    安装搜狗输入法 点击我下载哦 idea快捷键冲突 输入发占用快捷键.撤掉输入法的快捷键.还有系统自带快捷键也要取消. 安装deepin-terminal 在tools工具包中找到deepin-term ...

  2. 常用Linux备份

    用于备份的Tar 备份工具Tar是以前备份文件的可靠方法,几乎可以工作于任何环境中,Linux老用户一般都信赖它. Linux中以.tar结尾的文件都是用tar创建的.它的使用超出了单纯的备份,可用来 ...

  3. CocosCreator上的游戏(调试)发布到微信小程序

    1.下载CocosCreator,微信开发者工具 官网地址:http://www.cocos.com/download 官网下载:https://developers.weixin.qq.com/mi ...

  4. Codeforces 220C

    题意略. 思路: 我们可以把 bi[ i ] 在 ai[ ] 中的位置记录下来,然后算出 i - mp[ bi[i] ] ,再将它压入一个multiset.每次我们就二分地来寻找离0最近的数字来作为答 ...

  5. ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名

    ABP默认的MVC启动模板在登录后, 右上角显示的是用户名: 如果想让它显示用户的姓名该如何做呢?这就需要用到ABP一个非常强大的功能------虚拟文件系统. 前期准备 使用ABP CLI创建一个名 ...

  6. Requests方法 -- 参数关联与JSESSION(上一个接口的返回数据作为下一个接口的请求参数)

    前言 参数关联是接口测试和性能测试最为重要的一个步骤,很多接口的请求参数是动态的,并且需要从上一个接口的返回值里面取出来,一般只能用一次就失效了.最常见的案例就是网站的登录案例,很多网站的登录并不仅仅 ...

  7. 【Linux命令】nohup命令

    nohup命令 不挂断的运行,它会使您的脚本被忽略SIGHUP,并重定向stdout/stderr到一个文件nohup.out,以便在您注销后该命令可以在后台继续运行. 1)语法 nohup Comm ...

  8. P2059 [JLOI2013]卡牌游戏 概率DP

    link:https://www.luogu.org/problemnew/show/P2059 题意: 有n个人,类似约瑟夫环的形式踢人,但是报的数是不同的,是在给定的许多数中随机抽取,问最后第i个 ...

  9. cogs2823求组合数(lucas定理

    http://cogs.pro:8080/cogs/problem/problem.php?pid=vNQJJVUVj 再写个数学水题,其实lucas适用于m,n比较大而p比较小的情况. 题意:给出两 ...

  10. CodeForces 804C Ice cream coloring

    Ice cream coloring 题解: 这个题目中最关键的一句话是, 把任意一种类型的冰激凌所在的所有节点拿下来之后,这些节点是一个连通图(树). 所以就不会存在多个set+起来之后是一个新的完 ...