算法题 - 拼凑面额 - Python

189 篇文章 3 订阅

问题描述:

拼凑面额

给你六种面额15102050100元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N0-10000的非负整数)的不同组合的个数。

输入描述: 输入为一个数字N,即需要拼凑的面额
输出描述: 输出也是一个数字,为组成N的组合个数。
示例
输入:5
输出:2

题目来源

问题分析:

经典题目,类似于背包问题或者上台阶问题(上台阶问题只有两种情况,而这个有几种面额零钱就有多少种情况),昨天晚上58到家的现场宣讲会笔试题,其实牛客网上也有的,链接已经给出。现在总结一下,动态规划解决,具体思路如下:

(1)设 dp[n,m] 表示 N元钱,且有零钱M种时,不同组合数。并且,把零钱放到nums=[1, 5, 10, 20, 50, 100] 。(后面的m,都可以理解为第m种零钱,或者当前有m种零钱即可)

(2)现在思考 dp[n,m] 怎么求?很容易联想到上台阶问题,要想得到dp[n,m] 的值,一定是从 ∑ j = 0 m d p [ n − n u m s [ j ] , m ] + d p [ n , m − 1 ] \sum _{j=0} ^{m}{dp[n-nums[j], m]}+dp[n, m-1] j=0mdp[nnums[j],m]+dp[n,m1] 得到的,具体点:

  A、当m相等时,当前状态一定是前m种状态的总和,即, ∑ j = 0 m d p [ n − n u m s [ j ] , m ] \sum _{j=0} ^{m}{dp[n-nums[j], m]} j=0mdp[nnums[j],m]

  B、当n相等时,很显然当前有m种零钱,它情况一定包含m-1种零钱的所有情况,即, d p [ n , m − 1 ] dp[n, m-1] dp[n,m1]

  C、最后 dp[n,m] 就是这两种情况的

要注意的是n-nums[m]>=0 是前提条件。所以得出状态转移方程为:

  1. n >=nums[j] 时: d p [ n , m ] = d p [ n , m − 1 ] + ∑ j = 0 m d p [ n − n u m s [ j ] , m ] dp[n,m]=dp[n, m-1]+\sum _{j=0} ^{m}{dp[n-nums[j], m]} dp[n,m]=dp[n,m1]+j=0mdp[nnums[j],m]
  2. n < nums[j] 时: d p [ n , m ] = d p [ n , m − 1 ] dp[n,m]=dp[n, m-1] dp[n,m]=dp[n,m1]
  3. 此外就边界情况,均为1

(3)dp空间压缩,先看一下下面得图片:
在这里插入图片描述
dp[10,2] = dp[10,1] + dp[0, 2] = 3 + 1 = 4 在结合上面的公式不难发现,当前值,只和上面一行的值(情况B),还有本行的值(情况A)有关,所以,现在可以压缩一下dp空间,即,一行一行的计算。

Python3实现:

# @Time   :2018/10/12
# @Author :LiuYinxing
# 动态规划 - 类似于背包问题、上台阶问题


class Solution:
    def solve(self, n):
        nums = [1, 5, 10, 20, 50, 100]  # 基本面额
        dp = [1] * (n + 1)  # 初始化dp

        for j in range(1, 6):
            for i in range(1, n+1):
                if i >= nums[j]:  # 约束条件
                    dp[i] += dp[i - nums[j]]
        return dp[-1]

    def solve1(self, n):
        nums = [1, 5, 10, 20, 50, 100]  # 基本面额
        dp = [0] * (n + 1)  # 初始化dp
        dp[0] = 1  # 初始化dp

        for j in range(6):
            for i in range(nums[j], n+1):
                # if i >= nums[j]:  # 约束条件
                dp[i] += dp[i - nums[j]]
        return dp[-1]

if __name__ == '__main__':
    solu = Solution()
    print(solu.solve(n=7))

声明: 总结学习,有问题或不妥之处,可以批评指正哦。

[1] 题目/参考-链接:www.nowcoder.com/questionTerminal/14cf13771cd840849a402b848b5c1c93

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
算法图解-python.pdf》是一本介绍算法和使用Python语言实现算法的书籍。该书的目的是帮助读者了解算法的基本概念和原理,并通过Python编程实践来加深理解。 这本书以图解的方式呈现算法的思想和应用,使复杂的算法变得直观易懂。读者可以通过阅读该书,学习到各种常见的算法设计和解决思路,如排序算法、搜索算法、图算法等。同时,该书也会介绍一些高级算法,如动态规划、贪婪算法等,以及如何通过Python语言实现这些算法。 《算法图解-python.pdf》的内容结构清晰,通俗易懂。每个算法都有详细的解释和示例代码,读者可以通过实际编程来加深对算法的理解。此外,书中还包含了一些挑战性的练习,供读者进一步巩固所学的知识。 通过阅读《算法图解-python.pdf》,读者不仅可以学习到算法的基本知识,还可以了解到如何运用Python语言实现这些算法。这对于刚开始学习算法Python编程的读者来说是非常有帮助的。无论是计算机科学专业的学生,还是对算法感兴趣的爱好者,都可以从这本书中受益匪浅。 总之,《算法图解-python.pdf》是一本很好的算法入门书籍,以图解和Python编程为特色,适合各类读者学习和参考。通过阅读和实践,读者可以提高算法设计和编程实现的能力,为解决实际问提供有效的思路和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值