python每日一练:硬币划分(多方法详解)

news2024/11/17 15:53:43

文章目录

  • 前言
  • 0、题目
  • 一、暴力总是不能解决问题的
  • 二、还能更暴力一点
  • 三、减少暴力思想
  • 四、引入先进思想
  • 总结


前言

这题挺有意思的,典型的背包组合问题,虽然没有要求各种组合方式,不过我们可以试试给出组合方式。当然这题不太可能用一行代码解决了…来看一行超人的可别失望了~ 本文满满的干货!写了两天呢!
先上100分图:
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

0、题目

题目描述:
有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n<100000),有多少中组合可以组成n分钱?

输入描述:
输入整数n.(1<=n<=100000)

输出描述:
输出组合数,答案对1e9+7取模。

一、暴力总是不能解决问题的

老规矩,遇到问题先暴力一波!

代码如下(示例):

def force(n):
    res = 0
    for i in range(n+1):
        for j in range(n//2+1):
            for k in range(n//5+1):
                for l in range(n//10+1):
                    if i + j*2 + k*5 + l*10 == n:
                        res += 1
    return res
    
if __name__ == "__main__":
    n = 1000
    result = force(n)
    print(result)

多么的错落有致的代码!太优美了。可惜好看归好看,好写也是真好写,n=100时,它费了一秒钟就算出来2156了!但当n=1000时,它就算不出来了!这破代码幼儿园小朋友扳手指头都比它强!丢远点~

二、还能更暴力一点

明显可以模拟实际情况一个个取硬币来实现,最多有四种面额,就循环四次,每次取一个,不够值就递归去取,一直取到n==0,就是一种方法,添加到列表。想法很好!

代码如下(示例):

def reduce(n, path=[]):
    coins = [10, 5, 2, 1]
    res = []  # 初始化结果列表
    if n == 0:  # 如果n为0,说明已经找到了一种方案
        res.append(path)  # 将这个方案添加到结果列表中
        return res  # 返回结果列表
    for coin in coins:  # 遍历硬币面额
        if n >= coin:  # 如果当前硬币面额小于等于n
            new_path = path + [coin]  # 更新path,加入新取的硬币
            res += reduce(n - coin, path=new_path)  # 继续递归,更新n和path
    return res  # 返回结果列表

if __name__ == "__main__":
    n = 100
    result = reduce(n)
    result = [sorted(v) for v in result]
    res = []
    for x in result:
        if x not in res:
            res.append(x)
    print(res.__len__())

果然能成,n=10的情况,biu一下就算出来11了,因为给出的是各种取法,所以要去重。最后列表len值就是方法数了。可惜正如笔者在博文小议递归:https://blog.csdn.net/alal001/article/details/130436551中所写,这种干重复活的递归都是不靠谱的!这破玩意连n=100都算不出来!我也算不出这玩意的时间复杂度了…

三、减少暴力思想

很明白的看出,越暴力越不能解决问题!
递归是可以拆解的,我们就就把它拆简单点,毕竟计算机是机械的执行命令的。咱也不要硬币的组成的方式了,数字大了真顶不住的!

稍微想想就知道,只用1分的硬币,组成任何数都只有一个办法。
只用2分和1分的硬币,不计全1分的情况就是n//2个情况。
哈~ 咱是正经小学毕业的!算不出来用1,2,5三种的情况了。没关系这部分交给计算机算。

代码如下(示例):

def only_125(n):   # 这是只用1、2、5的情况
    only_12 = lambda n: n//2   # 这是只用2的情况
    res = 0
    while n > 0:
        if n < 5:
            res += only_12(n)
            break
        else:
            res = res + 1 + only_12(n)
            n -= 5
    return res
    
def main(n):     # 主函数
    only_1 = 1   # 这是只用1的情况
    res = 0
    while n > 0:
        if n < 5:  
            res += n//2
            break
        elif n < 10:   
            res = res + 1 + n//2   # 加1是有一个5的情况,n//2是全1、2的情况
            n -= 5   # 减掉一个5后,余下转到小于5处理
        else:
            res = res + only_125(n) + 1
            n -= 10
    return res + only_1
    
if __name__ == "__main__":
    n = 100000
    print(main(n))

这逻辑就够简单明了,而且效率大幅提升! n = 100000 虽然用了几秒,但也算出来了。就还是不能过网页测试…
嗯~ 再把1、2、5三种的组合情况简化一下就行了!但那就成纯数学公式了,体现不了咱的技术水平,嗯~ 主要咱也推导不出那公式…

四、引入先进思想

痛定思痛,咱学习数学去,小学数学老师总是教导我们要找规律:
咱换个想法,靠计算估计只能去解决上面的1、2、5组合的简化方法了。所以数学不好就别计算了,咱画表格!假设存在一张表格,里面记录了各种硬币组成n的数量…咱查表就解决了,这就老快了!
那么问题转移到如何生成这张表格了!也就是如何找规律的问题:

代码如下(示例):

def dpway(n):
    dp = [0] * (n + 1)  # 初始化dp数组,dp[i]表示组成i分钱的方案数
    dp[0] = 1  # 初始化dp[0]为1,因为组成0分钱只有一种方案,即不选硬币
    for coin in [1, 2, 5, 10]:  # 遍历硬币面额
        for i in range(coin, n + 1):  # 遍历每个分钱数
            dp[i] = (dp[i] + dp[i - coin])  # 计算组成i分钱的方案数

    return dp[n]  # 返回组成n分钱的方案数

if __name__ == "__main__":
    n = 100
    #result = force(n)
    #result = reduce(n)
    result = dpway(n)
    print(result)

首先,定义了一个长度为n+1的数组dp,其中dp[i]表示组成面额为i的方案数。然后,将dp[0]初始化为1,因为组成0分钱只有一种方案,即不选硬币。

接下来,遍历硬币面额1、2、5、10四个不同的面额。对于每个硬币面额,使用两个嵌套的循环遍历每个分钱数i,计算组成i分钱的方案数,即dp[i]加上dp[i-coin]。最后,返回dp[n],即组成n分钱的方案数。如:表格会生成dp[1]为1,dp[2]为2…

此动态规划法已经很精简了,理解也有点不能了,如果用二维数组会好理解一点。也因为没有规划过程,所以没法得出每一种方案。


总结

希望本博文能对各位看官理解递归和动态规划有点帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/496986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 从入门到精通系列讲解 - 总目录

&#x1f466; 作者介绍&#xff1a;Bazinga bingo&#xff0c;专注C语言应用硬核干货分享&#xff0c;潜心修炼&#xff0c;虚心学习&#xff0c;立志做嵌入式相关赛道的Top。 &#x1f4d5; 本文收录于《STM32开发》专栏&#xff0c;包含STM32内部模块介绍、片内资源开发、不…

如何使用bingChat(使用方法+遇到的问题+感受)

文章目录 前言一、如何使用Bing Chat1. 下载new Bing2.重新注册一个microsoft&#xff08;此步骤可略过&#xff0c;如有问题再操作此步骤&#xff09;3. 使用 Bing Chat 二、常见问题1.Chat mode is only available when you have access to the new Bing.2. 网页上没有“聊天…

leetcode 104——二叉树的最大深度

文章目录 题目详情方法一 万能的递归方法二 通过使用层序遍历的方式Java完整代码递归实现非递归实现——借助队列 题目详情 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 l…

yolov5图像识别voc转yolo代码解析

https://github.com/ultralytics/JSON2YOLO https://blog.csdn.net/qq_51831335/article/details/127237772 目标检测数据集标签转换COCO2VOC、YOLO2VOC、JSON2YOLO <annotation><folder>VOC2007</folder><filename>000001.jpg</filename><s…

x265码控分析

D和R的关系 高分辨率量化 均匀量化&#xff1a;量化区间 ‘ Δ k y k − y k − 1 ‘ \Delta_ky_k-y_{k-1} ‘Δk​yk​−yk−1​‘&#xff0c;近似为常数&#xff1b;p(x)为信源概率密度函数&#xff0c;且 ‘ Δ k ‘ \Delta_k ‘Δk​‘的大小相对于p(x)的变化率充分小&…

【模拟IC学习笔记】 反馈

反馈的作用&#xff1a;增益灵敏度降低 采用开环的方式实现一个精确的增益比较困难&#xff0c;但是可以实现高增益。 增益灵敏度衍生出来的另外两个特点 1、增加系统带宽。 2、改变输出阻抗&#xff0c;提高驱动能力。 反馈的作用&#xff1a;增加带宽 带宽的增加来源于…

对传递函数的零极点、频率响应、稳定性的理解

对传递函数的零极点、频率响应、稳定性的理解 零极点 从传递函数求零极点 令传递函数分子为0求出零点&#xff0c;令分母为0求出零点。 频率响应 单极点系统的频率响应 A v A v d c ∗ ( 1 / ( 1 s R C ) ) AvAv_dc*(1/(1sRC)) AvAvd​c∗(1/(1sRC))&#xff0c;系统的极…

python通过SSH管道访问ClickHouse

目录 前言什么是跳板机什么是SSH协议SSH管道访问ClickHouse参考文献 前言 因为新业务需要&#xff0c;数据都存储在阿里云服务器的ClickHouse数据库里&#xff0c;最近想取点数探索一下&#xff0c;于是下载了客户端工具DBeaver并成功连接ClickHouse&#xff0c;然后想通过pyt…

【前端面试题】这些js功能你一定要学会

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 1.图片失败&#xff0c;重新加载 如果图片资源不存在&#xff0c;那可以设置图片失败的占位…

深度学习——A3C算法

A3C算法&#xff08;Asynchronous Advantage Actor-Critic&#xff09; DDPG算法之后&#xff0c;DeepMind对其改造&#xff0c;提出了效果更好的 Asynchronous Advantage Actor-Critic&#xff08;A3C&#xff09;算法&#xff08;论文是 Asynchronous Methods for Deep Rein…

【谷粒商城之远程调用和异步调用丢失请求头问题】

本笔记内容为尚硅谷谷粒商城远程调用和异步调用丢失请求头问题部分 目录 一、Feign远程调用丢失请求头 二、Feign异步调用丢失请求头问题 一、Feign远程调用丢失请求头 ​ ​ 问题&#xff1a; feign在远程调用之前要构造请求&#xff0c;调用了很多的拦截器。 浏览器发送请…

u01使用率100%报错归档满的问题

今天下午客户报数据库无法连接了&#xff0c;我也立刻登录查看 因为显示orcl1归档满了&#xff0c;我就登录查看磁盘组的空间&#xff0c;发现空间空余很多 就sqlpus登录了&#xff0c;发现u01使用率满了 [oracledb1 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 …

《面试1v1》动态代理

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 那你能说一下反射和动态代理的关系吗&#xff1f; 候选人&#xff1a; 当然可以。动态代理是一种基于反射的机制&#xff0c;它可以在运行时动…

动设备维护管理的新趋势——在线监测与故障诊断系统

随着工业自动化水平的提高&#xff0c;动设备在现代工业中扮演着越来越重要的角色。然而&#xff0c;动设备故障率高、维修难度大、维护费用高是工厂面临的重要挑战之一。针对这些问题&#xff0c;在线监测与故障诊断系统逐渐成为动设备维护管理的新趋势。 图.设备工程师正在维…

Spring Cloud Alibaba: Gateway 网关过滤器 GatewayGatewayFilter factory (记录)

目录 AddRequestHeader GatewayFilter factory AddRequestHeadersIfNotPresent GatewayFilter factory AddRequestParameter GatewayFilter Factory AddResponseHeader GatewayFilter Factory CircuitBreaker GatewayFilter factory circuit breaker based on the status…

真题详解(构造二叉树)-软件设计(六十八)

真题详解&#xff08;归纳法&#xff09;-软件设计&#xff08;六十七)https://blog.csdn.net/ke1ying/article/details/130517187 CMM能力成熟模型 CL0(未完成)&#xff1a;过程域未执行或未得到定义的目标。 CL1(已执行)&#xff1a;将可标识的输入工作产品转换成可标识的…

数组中的empty剖析

数组中的empty剖析 一、首先empty是怎么来的 直接通过new Array来新建&#xff0c;手动修改数组的length&#xff0c;逗号之间没有任何数据等 const array new Array(3); console.log(array); //* (3) [empty 3]const array2 [1, , 3]; console.log(array2); //* [1, e…

【软考|软件设计师】进程p1,p2,p3,p4,p5和p6的前趋图

目录 题目&#xff1a; 答&#xff1a; 题目&#xff1a; 进程p1,p2,p3,p4,p5和p6的前趋图如下图所示。用PV操作控制这6个进程之间同步与互斥 的程序如下&#xff0c;程序中的空(1)和空(2)处应分别为________,空(3)和空(4)处分别为________, 空(5)和空(6)处应分别为_______…

数据结构:图的插入和删除

线性表中我们把数据元素叫元素&#xff0c;树中将数据元素叫结点&#xff0c;在图中的数据元素我们称之为顶点&#xff08;Vertex&#xff09;。 线性表中可以没有数据元素&#xff0c;称之为空表。树中可以没有结点&#xff0c;叫做空树。但图没有空图。 线性表中&#xff0c;…

2023年好用的MacBook文件管理软件推荐

我们已经有多年的 macOS 编程经验&#xff0c;也开发了很多大家都可以使用的工具。 我们可以解决各种 Mac 问题。 CleanMyMac X 这里是一些小建议&#xff1a;下载 CleanMyMac 即可快速解决本文章中提到的一些问题。但是&#xff0c;为了帮助您自行操作&#xff0c;我们还整理…