硬币找零问题-解释

我希望提供有关此问题的动态编程解决方案的分步演练。

本文假设读者已经精通递归解决方案。 如果对此有很多疑问,我将通过编辑此帖子进行跟进。 或者我可能还是会回来编辑它。

让我们从看代码开始。 我将使用Python并分解脚本关键部分中发生的情况。 这称为自下而上的方法,因为我们正在逐步提升索引,而不是通过递减索引直到终止来实现递归。

该函数采用S(硬币列表),m(硬币列表的长度)和n(我们要组成的零钱)。 在本文中,我们将使用S = [1,2,3]和n = 4的简单但具有代表性的情况。

在下面的红色框中,我们只是在构造一个列表列表,列表的长度为n + 1。 我们首先将各个列表中的所有值初始化为0。然后,将表中的第一个列表初始化为全1。 为什么会这样呢? 让我们继续了解原因。

查找组合数量的功能。

首先,让我们开始完全了解并理解下图。 在n = 4和S = [1,2,3]的情况下,

我们将使用的变量如下:S是输入列表,j是跟踪每个S的索引。表中列表的数量初始化为n + 1,以适应n = 0的基本情况。 为什么它们充满“ 1”? 这样,程序将在n = 0时始终返回1,类似于对此问题的递归解决方案。

接下来,让我们看看嵌套的for循环中发生了什么。

我们将遍历表中从索引1开始的每个列表,并且在每次迭代中,我们将遍历S。这样,我们就可以累积计算,并且能够避免重复的计算向前发展。

通过在嵌套的for循环中实现它并增加索引,我们将其称为自底向上方法。

嵌套的for循环代表什么

现在到了棘手的部分(至少对我来说是这样)。 让我们关注嵌套的for循环内的两个语句。 从表n = 1开始,对表中每个列表中的每个元素执行这两个语句。

让我们看一下两行代码:

与递归解决方案类似,对于内循环的每次迭代,我们都希望获得强制包含S [j]并将其存储在x中的解,还希望获得强制排除S [j]并将其存储在y中的解。 这样,我们将能够引用较早的解决方案,以避免重复计算。

为什么要这样在每次计算中包含和排除硬币S [j]?

解释很简单。 对于每种硬币,只能有两种可能性。 考虑使用n值包含或排除它。 并且我们知道,如果硬币(S [j])大于n,则x将返回0,因为将其考虑在内是不可能的。

现在,让我们从两个问题开始:

1. i_S [j]的意义是什么?

S [j]之后参考的先前i的值取自i。 强制包含S [j]。

2.为什么引用[j]?

我们想引用S中相同的位置,即S [j],只是在不同的n处。

3.为什么将它用作表数组的索引?

引用n数组的早期计算。

这两个语句是什么意思:

1. 第一句话

通过使S [j]为强制性,我们从i中减去S [j]并参考过去计算的n,其中n = i_S [j]。

2. 第二条陈述

通过引用先前计算的S [j] = S [j] _1找出所有不包含S [j]的解决方案。让我们深入研究。

让我们深入探讨第二个陈述:

1. [i] [j-1]的意义是什么?

在S的前一个元素中引用相同的n。

2. 为什么当j <1时总是返回0?

当j = 0时,我们不考虑任何S [j]。

3.在这种情况下,列表S是否必须排序?

不,因为我们累积地遍历m朝着j = m的方向努力,并且只对最终情况感兴趣。

4.使用S [0]和S [2]但不使用s [1]的情况如何?

我们不需要进行计算,因为最终我们想知道在迭代硬币数组中的所有硬币之后,对于i == n存在多少个解决方案。

现在,让我们开始运行带有测试值的嵌套for循环。

让我们遍历嵌套的for循环。

以上步骤的图示。

我希望这篇文章能够对尝试了解此问题的人有所帮助。 请原谅我没有真正花时间在美学上,希望内容能弥补这一点。

另请参阅Geeksforgeeks网站上的Dynamic Programming Solution,并阅读以下文章:

From: https://hackernoon.com/the-coin-change-problem-explained-ddd035a8f22f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值