​ 给定数组 arr,arr 中所有的值都为正整数。每个值代表一张钱的面值,再给定一个整数 aim 代表要找的钱数,求组成 aim 的最少货币数。

举例

  • arr= 【5,2,3】,aim = 20;返回 -1

    • 5 元,2元,3元的钱各有 1 张,无法组成 20 元,返回默认值 -1
  • arr= 【5,2,5,3】,aim = 10;返回 2
    • 2 张 5 元
  • arr= 【5,3】,aim=0;返回 0
    • 不用任何货币就可以组成 0 元

解法一:暴力递归

f ( i,rest) 定义:使用 arr[ 0 : i+1] 的货币并且 aim = rest 时的最小货币数。

最终返回结果:f ( len(arr) - 1,aim )

可能性分类:

  • 保留当前货币 arr[i] 的子问题:num1 = f( i -1, aim - arr[i] ) + 1
  • 不保留当前货币 arr[i] 的子问题:num2 =f( i -1, aim )
  • 决策: min(num1,num2) :注意判断返回值的有效性(num1 != sys.maxsize),无效返回值表示此路不通,需要丢弃。

base case

  1. 无效参数:i < 0 or rest < 0
  2. 如果有货币等于 rest ,那么最小货币数为 1
import sysdef min_coins(array, aim):res = f(array, len(array) - 1, aim)return -1 if res == sys.maxsize else resdef f(array, i, rest):# base caseif i < 0 or rest < 0: return sys.maxsizefor j in range(i + 1):if array[j] == rest: return 1# 不保留 arr[i]num1 = f(array, i - 1, rest)# 保留 arr[i]num2 = f(array, i - 1, rest - array[i])res = sys.maxsizeif num1 != sys.maxsize:res = num1if num2 != sys.maxsize:res = min(res, num2 + 1)return res

解法二:动态规划

f 函数有两个变量

  • i:货币数组的下标(在dp 中为行)
  • rest:剩余钱数(在 dp 中为 列)

def min_coins2(array, aim):if aim < 0 or not array: return -1if aim <= 0: return 0n = len(array)dp = [[sys.maxsize] * (aim + 1) for _ in range(n)]# base caseif array[0] <= aim: dp[array[0]] = 1for i in range(1, n):for j in range(aim + 1):left_up = 1 if array[i] == j else sys.maxsizeif j - array[i] >= 0 and dp[i - 1][j - array[i]] != sys.maxsize:left_up = dp[i - 1][j - array[i]] + 1dp[i][j] = min(left_up, dp[i - 1][j])return dp[-1][-1] if dp[-1][-1] != sys.maxsize else -1

解法二:滚动数组

滚动数组是从上向下滚动,填充充从右向左填充。

def min_coins3(array, aim):if aim < 0 or not array: return -1if aim <= 0: return 0n = len(array)dp = [sys.maxsize] * (aim + 1)# base caseif array[0] <= aim: dp[array[0]] = 1for i in range(1, n):for j in range(aim, -1, -1):# base caseleft_up = 1 if array[i] == j else sys.maxsizeif j - array[i] >= 0 and dp[j - array[i]] != sys.maxsize:left_up = dp[j - array[i]] + 1dp[j] = min(left_up, dp[j])return dp[-1] if dp[-1] != sys.maxsize else -1

对数器

import randomdef generator_random_arr(max_size, max_value):return [int(random.random() * max_value) + 1 for _ in range(int(random.random() * max_size) + 1)]def check():max_size = 10max_value = 10for _ in range(1000):arr = generator_random_arr(max_size, max_value)aim = int(random.random() * sum(arr)) + 1res = min_coins(arr, aim)res2 = min_coins2(arr, aim)res3 = min_coins3(arr, aim)if res != res2 or res != res3:print("ERROR", "res=", res, "res2=", res2, "res3=", res3, aim, arr)print("OVER")check()

【每日一题】最少货币数相关推荐

  1. 牛客题霸 [ 换钱的最少货币数] C++题解/答案

    牛客题霸 [ 换钱的最少货币数] C++题解/答案 题目描述 给定数组arr,arr中所有的值都为正整数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱 ...

  2. 换钱的最少货币数(NC126/考察次数Top69/难度简单)

    描述: 给定数组arr,arr中所有的值都为正整数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数. 如果无解,请返回-1. ...

  3. 动态规划-换钱最少货币数

    #encoding:utf-8 _author_ = "Wang Wenchao" #换钱最少的货币数 #给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币 ...

  4. python 货币合适_算法之Python实现 - 001 : 换钱的最少货币数

    [题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额外 ...

  5. 20200720:每日一题之两数之和Ⅱ(leetcode167)

    每日一题之两数之和Ⅱ 题目 思路与算法 代码实现 复杂度分析 题目 思路与算法 今日份笑点如下: 暴力遍历,视为TLE 双指针左右移动,根据大小判断左指针右移还是右指针左移,清晰易懂,为正解. 代码实 ...

  6. 牛客 换钱的最少货币数

    题目链接:https://www.nowcoder.com/practice/4e05294fc5aa4d4fa8eacef2e606e5a8?tpId=101&tqId=33080& ...

  7. Python换钱的最少货币数

    题目: 给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,代表要找的钱数,求组成aim的最少货币数. 例: arr = [ ...

  8. 最少钱币数不java,【动态规划专题】3:换钱的最少货币数

    <程序员代码面试指南--IT名企算法与数据结构题目最优解> 左程云 著 换钱的最少货币数 [题目] 给定数组arr, arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的 ...

  9. 动态规划问题——换钱的最少货币数

    题目: 给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,在给定一个整数aim,代表要找的钱数,求组成aim的最少货币数. 示例: arr = ...

最新文章

  1. Java中的多线程你只要看这一篇就够了
  2. 简单回声服务器的实现
  3. Spring源代码学习之How is Beans.xml loaded and parsed
  4. 基于 OpenFire 的TVBox管理平台开发笔记
  5. C++基础::函数、类、类型所在的头文件 接口的介绍
  6. 小试牛刀之Kolla单节点部署
  7. 课时4.浏览器请求数据的过程(理解)
  8. 浅谈聚类分析MATLAB实现
  9. 《Redis视频教程》(p5)
  10. 易优CMS:arcpagelist 瀑布流分页列表
  11. 炼丹笔记一——基于TensorFlow的vgg16的cifar10和100简单探究超参数对训练集收敛情况的影响
  12. SpringAOP基础以及四种实现方式
  13. 只要7步,就能将任何魔方6面还原(留着以后教孩子玩)
  14. Java——匿名内部类
  15. 微信公众平台测试帐号的注册与使用
  16. 安卓adb工具的使用
  17. Android 获取ROOT权限原理介绍和签名验证原理及反编译学习
  18. MD编辑器就是不告诉你之表情
  19. 高等教育心理学:教师职业心理(完) 不是特别重要
  20. 会话(gorilla/sessions)

热门文章

  1. 哈希表哈希碰撞解决办法
  2. node爬虫(入门)
  3. blazeds TypeError: Error #1034: 强制转换类型失败
  4. 【正一专栏】《使徒行者2》——难得追完的剧
  5. Windows关闭123、137、138、139、445、1900等端口监听指引
  6. Python 图像对比度增强的几种方法
  7. matlab 比较两个结构体,用于比较 MATLAB 结构体数组的比较器 - MATLAB - MathWorks 中国...
  8. Editplus打开关联文件缓慢的问题解决
  9. Js生成指定长度和基数的UUID
  10. 分享九种Python制作的圣诞树,看完长津湖你还想过圣诞吗?可是圣诞不是哪个国家的专属节日呀~