面试题 08.11. 硬币

面试题 08.11. 问题描述

  硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)

在这里插入图片描述在这里插入图片描述
解题思路1.错误思路,首先想到的就是回溯法,画出解法空间
在这里插入图片描述
  对于n=25找零方式可以分解为四个解空间,然后再对子空间进行分解,很容易用递归完成。
代码如下

class Solution:
    def __init__(self):
        self.num = 0 #总次数
    def waysToChange(self, n: int) -> int:
        def res(n):
        	if n==0:#每次当n为0时候,即表示到了解空间的叶子节点,这条路径即为一种解法
            	self.num+=1
        	for i in [1,5,10,15]: #对每一层都进行回溯过程
            	if n>=i: 
                	self.waysToChange(n-i)
        return self.num%1000000007

  run完之后发现结果不对,这里是不同解做了一个类似去全排列的过程,假如25分解,上面的做法会出现[5,10,5,5,5],[10,5,5,5,5]这些解法,仅仅是位置不同而已,所以如果对最后的结果进行一个排序去重的话,可以算出正确的找零方式,目前还没什么好的思路,估计如果能实现的话,估计复杂度也过不了。

正确思路,动态规划:本题有两个变量硬币的种类数k,找零的总数v,问题可描述为对(k,v)求解,表示为f(k,v)
  冷静思考一下,考虑怎么分解为子问题,很容易想到,如果种类数k少一种ki的话,是怎样的一种对应关系,是不是对应的是去掉所有包含ki这一硬币,ki是不是有可能是0个,对应f(k-1,coins[ki]*0)这么多种情况;也有可能是1一个,对应f(k-1,coins[ki]*1)这么多种情况;ki最多的个数为v整除coins[ki],假设为n个,即可得到状态转移方式为:
f ( k , v ) = f ( k − 1 , v − 0 ∗ c o i n s [ k i ] ) + f ( k − 1 , v − 1 ∗ c o i n s [ k i ] ) + . . . f ( k − 1 , v − n ∗ c o i n s [ k i ] ) f(k,v) = f(k-1,v-0*coins[ki])+f(k-1,v-1*coins[ki])+...f(k-1,v-n*coins[ki]) f(k,v)=f(k1,v0coins[ki])+f(k1,v1coins[ki])+...f(k1,vncoins[ki])
  找到了状态转移矩阵案例说用一个二维dp,然后双重循环就可以解决该问题了,但是对于每一个状态,里面还需要对n进行一个小循环,所以应该采用三种循环来解决。
时间复杂度优化 通过找规律很容易得到:
f ( k , v − c o i n s [ k i ] ) = f ( k − 1 , v − 1 ∗ c o i n s [ k i ] ) + f ( k − 1 , v − 2 ∗ c o i n s [ k i ] ) + . . . f ( k − 1 , v − n ∗ c o i n s [ k i ] ) f(k,v-coins[ki]) = f(k-1,v-1*coins[ki])+f(k-1,v-2*coins[ki])+...f(k-1,v-n*coins[ki]) f(k,vcoins[ki])=f(k1,v1coins[ki])+f(k1,v2coins[ki])+...f(k1,vncoins[ki])
原式可以写为:
f ( k , v ) = f ( k − 1 , v ) + f ( k , v − c o i n s [ k i ] ) f(k,v)= f (k-1,v)+f(k,v-coins[ki]) f(k,v)=f(k1,v)+f(k,vcoins[ki])
这可以解决里层n的循环,用两层循环表示状态转移矩阵
空间复杂度优化原本需要4(v+1)大小数组来保存所有的状态,通过观察可知k,v只和k-1,v和k,v-coins[ki]
的大小相关,k,v-coins[ki]在前面已知,而且在第k列中,而k-1,v我们可以作为临时值不保存也可以,只需在前面数组寻找v-coins位置的值,与其相加更新k值即可。

代码如下:

class Solution:

    def waysToChange(self, n: int) -> int:
        coins = [1, 5, 10, 25]
        dp = [1]+[0]*n
        for j in coins:
            for i in range(j,n+1):
                dp[i]+=dp[i-j]
        return dp[-1]%1000000007

代码非常简单,如果空间复杂度绕不过来,建议还是用二维dp数组来保存每一个状态,简答粗暴。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Bentley MicroStation V8i (SelectSeries 4) 08.11.09.833是一款功能强大的CAD软件,主要用于工程设计和建筑设计方面,支持2D和3D建模、渲染和动画等多种功能。其具有自动化工具、可自定义的界面、强大的图形编辑和处理能力、多种文件格式的支持等特点,可以帮助用户在设计过程中提高效率和准确性。此软件灵活便捷,使用范围广泛,不仅适用于建筑、土木工程、交通运输、水利工程等行业,还可以用于电力、制造业等其他领域。Bentley MicroStation V8i (SelectSeries 4) 08.11.09.833拥有丰富的功能模块,例如MicroStation Descartes可以支持地理空间和影像处理,而MicroStation PowerDraft可以用于绘图和草图设计等。这款软件还可以集成其他Bentley产品,如InRoads、GEOPAK、MX等,以扩展其功能和灵活性。总的来说,Bentley MicroStation V8i (SelectSeries 4) 08.11.09.833是一款功能强大且灵活多样的CAD软件,能够帮助用户快速高效地完成设计任务,是各行业专业人士不可或缺的工具之一。 ### 回答2: Bentley MicroStation V8i (SELECTseries 4) 08.11.09.833是一款用于CAD和GIS设计的软件。该软件具有强大的三维建模和2D绘图工具,可以用于建筑、土木工程、机械工程、电气工程等领域的设计和制图。它的设计界面简单易用,功能强大,可以轻松创建复杂的设计模型和项目。除此之外,该软件还支持多种文件格式的导入和导出,可以方便地与其他CAD软件进行兼容。此外,该软件还拥有灵活的协作工具和强大的云端支持,可方便团队合作。总体来说,Bentley MicroStation V8i (SELECTseries 4) 08.11.09.833是一款优秀的CAD和GIS设计软件,对于需要进行复杂项目设计和制图的专业人士来说,是非常有价值的工具。 ### 回答3: Bentley MicroStation V8i (SELECTseries 4) 08.11.09.833是Bentley公司推出的一个建筑设计软件,可以用于建筑、土木工程和电气设计等领域。这个软件在功能方面非常强大,可以进行3D建模、制图和渲染等操作,并且还支持多种文件格式的导入和导出。 在使用过程中,该软件提供了丰富的工具和功能,可以帮助用户高效地完成各种任务。其中包括高级的CAD绘图和编辑功能、多样化的标注和尺寸控制、灵活的图层管理和复杂线型设置等。 除此之外,该软件还具有强大的工作流程管理功能,可以帮助用户更好地协作和组织项目。例如,它提供了定制化的自动化工具,可以快速生成标准的设计图件,并支持多用户同时协作同一项目。 总之,Bentley MicroStation V8i (SELECTseries 4) 08.11.09.833是一款功能强大、易于使用的建筑设计软件,为用户提供了综合性的设计解决方案,可以满足各种不同领域的设计需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值