题解 | #兑换零钱(一)#

兑换零钱(一)

https://www.nowcoder.com/practice/3911a20b3f8743058214ceaa099eeb45

假设有面值为[1, 2,5, 10]的货币。要找23元,找23元的最少货币数作为果,可以有以下四种因

1、找13元的最少货币数+1,即找13元的方案再加一张10元就是23元了;

2、找18元的最少货币数+1,即找18元的方法再加一张5元就是23元了;

3、找21元的最少货币数+1,21+2=23

4、找22元的最少货币数+1,22+1=23

如果假设dp[i]表示要找i元时的最少货币数,则以上四种因对应的公式为

1dp[23]=dp[13]+1=dp[23-10]+1

2dp[23]= dp[18]+1=dp[23-5]+1

3dp[23]=dp[21]+1=dp[23-2]+1

4dp[23]= dp[22]+1=dp[23-1]+1

四种因中取最小的,即为dp[23],即找23元时最少的货币数。

而四种因中,dp[22],dp[21],dp[18],dp[13]又是采用同样的方法,求得要找的钱数对应的最小货币数,即迭代。

所以遍历所有的面值(假设i大于所有货币面值)

for j in range(len(arr)):

      dp[i] =min(dp[i],dp[i-arr[j]]+1)

这个min的过程,就是对应上面四种因求最小的过程。

至于为什么初始化dp[]时,让所有dp[i]的初始值为要找的钱数+1,是因为需要判断是否有解,再举个例子:

比如货币面值为3元,要找的钱数为1,2元时,显然没办法找,当要找的钱数为3元时,恰好1张,当找的钱数为4元时,又无法找开了,所以设置一个值来标记是否能找开的情况。为什么是aim+1呢,因为货币面值是正整数,1是最小的正整数,也就是如果有1元的货币的话,一定能找开,对应的货币数量就是aim本身,所以设置aim+1来对应不能找开的情况。

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 最少货币数
# @param arr int整型一维数组 the array
# @param aim int整型 the target
# @return int整型
#
class Solution:
    def minMoney(self , arr: List[int], aim: int) -> int:
        # write code here
        if aim <1:
            return 0
        # dp[i]表示如果要找的钱数为i,对应的最少货币数
        # 初始化,让初始最少货币数为aim+1,以在后面判断是否有解
        dp = [(aim+1) for i in range(aim+1)]
        dp [0] = 0 #要找的钱数为0时,对应的最少货币数为0,显然
        for i in range(1,aim+1):
            for j in range(len(arr)):
                if arr[j]<=i:
                    dp[i] = min(dp[i],dp[i-arr[j]]+1)
        if dp[aim]>aim:
            return -1
        else:
            return dp[aim]

全部评论

相关推荐

牛客279957775号:铁暗恋
点赞 评论 收藏
分享
09-25 10:34
东北大学 Java
多面手的小八想要自然醒:所以读这么多年到头来成为时代车轮底下的一粒尘
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务