问题:

给定不同面额的硬币(coins)和一个总金额(amount)。写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合方式能组成总金额,返回-1

示例 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)

示例 2:
coins = [2], amount = 3
return -1.

注意:

你可以认为每种硬币的数量是无限的。(此题目摘自leetcode)

什么是动态规划?其思路是为了求解当前的问题的最优解,使用子问题的最优解,然后综合处理,最终得到原问题的最优解。网上有很多介绍的文章,但是对于初学者(比如我)来说,看起来会有些懵。我个人的理解是,当总金额为amount时,所需的最少硬币个数为dp[amount],那么当amount = 11时,求出所有dp[1]、dp[2]、...、dp[11]的值。dp[1]到dp[10]就可以说是dp[11]的子问题,需要通过他们来求最终解。

以示例1为例,我们需要尽可能少的硬币个数,所以从11的总金额中取出任意一枚硬币,剩下的金额所需最少硬币个数再加上1就是所需硬币个数,即所需硬币个数为:dp[10]+1、dp[9]+1、dp[6]+1,再从中取最小值,即可求解。以此类推,dp[10]=min(dp[9]+1,dp[8]+1,dp[5]+1)...所以可以看出,通过求出所有dp[1]、dp[2]、...、dp[10]的值,最终就能得到dp[11]的值。

以下是代码实现:

def coinChange(coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
coins.sort() #给硬币从小到大排序
dp = {0:0} #生成字典dp,并且当总金额为0时,最少硬币个数为0
for i in range(1,amount + 1):
dp[i] = amount + 1 #因为硬币个数不可能大于amount,所以赋值amount + 1便于比较
for j in coins:
if j <= i:
dp[i]=min(dp[i],dp[i-j]+1)
#for i in range(1,amount + 1):
#print('dp[%d]:'%(i), dp[i])
if dp[amount] == amount + 1: #当最小硬币个数为初始值时,代表不存在硬币组合能构成此金额
return -1
else:

return dp[amount]

一开始不太理解,为什么要求金额11的解需要算出1-10的所有解,这样不是把问题弄得更复杂了吗?后来醒悟是思路问题,这有些递归的思想在里边,就像盖楼一样,你不可能不用1-10层就只盖个11层。之所以写这篇文章,是因为想保留我现在作为初学者的视角,等以后学习更深入些再回过头来说不定会有新的感悟,望大佬轻喷

零钱兑换问题——python动态规划解法相关推荐

  1. LeetCode:322. 零钱兑换(python)

    LeetCode:322. 零钱兑换(python) 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总 ...

  2. Python数据结构20:动态规划:找零兑换问题的动态规划解法并显示使用的硬币组合

    在我们使用递归算法时,可能会出现规模庞大的重复计算,用一个中间表记录每个计算过的最优解法,就可以避免大量的重复计算.中间结果记录可以很好解决找零兑换问题.实际上,这种方法还不能称为动态规划,而是叫做& ...

  3. 从放苹果问题到零钱兑换问题(动态规划)

    放苹果问题 题目描述 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. 数据范围:0<=m<=10,1 ...

  4. LeetCode刷题复盘笔记—一文搞懂完全背包之322. 零钱兑换问题(动态规划系列第十四篇)

    今日主要总结一下动态规划完全背包的一道题目,322. 零钱兑换 题目:322. 零钱兑换 Leetcode题目地址 题目描述: 给你一个整数数组 coins ,表示不同面额的硬币:以及一个整数 amo ...

  5. 518. 零钱兑换 II golang动态规划

    518. 零钱兑换 II 给定不同面额的硬币和一个总金额.写出函数来计算可以凑成总金额的硬币组合数.假设每一种面额的硬币有无限个. 示例 1: 输入: amount = 5, coins = [1, ...

  6. LeetCode 518. 零钱兑换 II(动态规划)

    1. 题目 给定不同面额的硬币和一个总金额. 写出函数来计算可以凑成总金额的硬币组合数. 假设每一种面额的硬币有无限个. 示例 1: 输入: amount = 5, coins = [1, 2, 5] ...

  7. LeetCode 322. 零钱兑换(DP)

    文章目录 1. 题目信息 2. 解题 2.1 回溯穷举 2.2 动态规划 1. 题目信息 给定不同面额的硬币 coins 和一个总金额 amount. 编写一个函数来计算可以凑成总金额所需的最少的硬币 ...

  8. 动态规划思路和Python解决零钱兑换问题和最大乘积子序列的乘积的问题

    动态规划(Dynamic Programming)思路和Python解题示例 动态规划是一种主要用来优化朴素递归的方法,每当输入不同值调用递归函数出现大量重复的(子)输入和调用(返回结果)时,就可以考 ...

  9. python解决换零钱问题_多种解法解决“零钱兑换”问题

    最近在LeetCode上刷算法题,准备秋招.刷了一些题之后,发现有些题非常棒,能够将多种知识点结合在一起.本文就以"零钱兑换"问题为例,展示同一道题的多种不同解法. 零钱兑换问题 ...

最新文章

  1. Java 项目UML反向工程转化工具
  2. 汇编中的数组分配和指针
  3. 户外私密Party | 在大峡谷里聊一点平时不能聊的干货(报名ing...)
  4. 8086指令(II)
  5. 常用工具类系列之DateUtil
  6. prototype与_proto_
  7. AJAX 网页保留浏览器前进后退等功能
  8. HBase 学习(三) JavaAPI的使用
  9. Android 自动更新之状态栏下载状态和进度
  10. H3C无线控制器做用户隔离和DHCP Relay的注意事项
  11. [Mysql] 3.Mysql 数据类型
  12. 记坑Method threw ‘feign.RetryableException‘ exception.
  13. 时间工具类、Instant、date、LocalDate、String、LocalDateTime 相互转换
  14. boost::string_algo库详解
  15. mongo3.5 java cursor_pymongo for py2.7.py3.6版本-pymongo下载3.5.1 官方最新版-西西软件下载...
  16. 3D查找表(3D LUT)说明
  17. 「跨链互连智能合约」解读
  18. 波浪螺旋型弹簧的画法
  19. NOIP模拟考栽阴沟了,惨痛爆零
  20. 分析Padavan源代码,二

热门文章

  1. 华为自研操作系统Project Z曝光
  2. Android 耳机检测原理介绍
  3. 少女时代动态android,少女时代攻「V APP」!连续8天live直播大放送
  4. matlab 定义函数 调用,matlab 定义函数,matlab定义函数并调用
  5. springboot毕设项目流动人口信息管理系统9i8kh(java+VUE+Mybatis+Maven+Mysql)
  6. 趣图:大佬如何解决bug的
  7. Datawhale 1月leetcode
  8. 智慧消防 物联网网关用于防火监测系统
  9. 2022危险化学品经营单位安全管理人员考试练习题及在线模拟考试
  10. python函数高级话题