当前位置: 首页 > 知识库问答 >
问题:

SICP计数变化问题为什么N=xy?

唐默
2023-03-14

我是一个潜伏的门外汉,试图自学CS,目前正在努力完成SICP的第一章。

我遇到了“计数变化”示例程序,像其他人一样,尽管我理解这个程序本身,但我正在努力解决它所基于的前提:

假设我们认为可用的硬币类型是按一定顺序排列的。那么以下关系成立:

使用n种硬币改变数量的方法数量等于

>

使用所有n种硬币改变金额的方式数量a-d,其中d是第一种硬币的面额。

要了解为什么这是真的,请注意改变的方法可以分为两组:不使用任何第一种硬币的方法和使用第一种硬币的方法。因此,对某一金额进行更改的方式总数等于在不使用任何第一种硬币的情况下对该金额进行更改的方式数,加上假设我们使用第一种硬币的情况下进行更改的方式数。但后一个数字等于使用第一种硬币后剩余的硬币数量的改变方法的数量。

问题和过程可以在上下文中找到,但我不会包括过程,因为这是我正在努力解决的逻辑,而不是过程本身。

我不明白的是,为什么这些都是平等的:

  1. “方式”的总数,减去在不使用第一种硬币的情况下获得全额的“方式”
  2. 在减去第一枚硬币的面额后,使用所有类型的硬币制作剩余金额的“方式”的数量

我已经手动运行了无数个测试示例,是的,这种关系成立,但是我不明白为什么。

他们解释的第一句话很有道理:

请注意,做出改变的方式可以分为两组:不使用第一种硬币的人和使用第一种硬币的人。

如果我们有“方法”的总数,我们可以根据这个规则将总数分成两组。没问题。

第二句话也很清楚:

因此,改变某一金额的方法总数等于在不使用第一种硬币的情况下改变该金额的方法数,加上假设我们使用第一种硬币的方法数一种硬币。

这只是说明,总的方法数是被分为两类的方法的总和。好啊

这就是他们失去我的地方:

后一个数字等于使用第一种硬币后剩余金额的变化方式的数量。

我假设这意味着“后一个数字”指的是所有必须使用第一面额中至少一枚硬币的改变方式。

为什么这个数字等于所有硬币的总金额减去第一枚硬币的面额的兑换方式的数量,以及如何与之相等?

为了试着想象这个问题,我重申了这一点,即试图在杠铃上达到80公斤的特定重量,有三种重量标准:

  1. 红色: 5Kg
  2. 绿色: 10Kg
  3. 蓝色: 20Kg

我把每个场景都视觉化了,确实这种关系成立了,但我仍然不明白为什么:

健美运动员的递归

感觉好像答案就在我的眼皮底下,但也许那个特定附属物的巨大尺寸会永远掩盖答案。

共有3个答案

施慈
2023-03-14

在其他回应者的帮助下,经过几天的思考,我认为这个问题可以通过在书的原始解释后面增加一个阐述来澄清(至少对我来说):

但是后一个数字等于使用第一种硬币后剩余的金额的变化方式的数量。

我将新段落措辞如下:

这是因为我们可以假设,对于每个组合,必须包含至少一种我们已经使用过的第一种硬币(“交给”)的一个实例。我们只需要计算出改变剩余n的方法。

因此,在以下方面进行改变的方式数量没有差异:

  1. 至少使用第一个面额中的一个面额的全额,以及
  2. n减去使用任意数量硬币的第一个面额的金额

随后,我成功地编写了该问题的“称重室”版本,其输出与我的视觉解决方案相匹配:

(define (loadways weight plates)
(cond
   [(= weight 0) 1]
   [(or (= (length plates) 0) 
        (< weight 0)
        ) 0]
   [else (+ (loadways weight (cdr plates))
            (loadways (- weight (car plates)) plates))]
   ))  

(define weight-rack (list 20 10 5))

(loadways 40 weight-rack)
任绪
2023-03-14

这里的诀窍是,考虑到一堆硬币的面额,其中一种我们称之为d,有两种方法可以兑换一定数量的a:

  • 不要使用任何面额为d的硬币
  • 至少使用一个d(我指的是“d”所指的“d”面额硬币)

而做出改变的方式总数就是这两种方式的总和(尤其是我们没有错过任何其他方式)。

所以,在第一种情况下,我们可以用除了d之外的所有面额来计算改变的方式的数量(我们显然要通过选择其他面额来做这件事

在第二种情况下,我们将使用至少一个d。所以我们知道,因为我们使用了至少一个d,所以A的量可以被拆分为A=d(A-d):这就是“使用至少一个d”的意思。那么现在有多少种方法可以组合成这样的硬币呢?答案是,这是一个数量(A-d)的改变方式的数量,但这次我们仍然可以使用ds来改变。

郑富
2023-03-14

让我们想象一种简化的货币,只有1和5面额。我要求你拿出15美元,条件是你给我的硬币中至少有一枚必须是5美元。你有多少种方法可以做到这一点?在这一点上,你可以尝试生成所有的方法来产生15的变化,然后扔掉所有不符合我要求的方法。但是很容易观察到,你也可以从留出一个5来满足我的需求开始,然后想出如何以你选择的任何方式改变剩下的10。

 类似资料:
  • 我是麻省理工学院开放式课程SICP课程的初学者,使用视频讲座和网上提供的书籍。昨天我遇到了一个例子,它问我们是否可以编写一个程序来计算改变任何给定金额的方法的数量。 这个问题有一个简单的递归解决方案: 如果你想查看更多,我从这里拿走了。 他们使用K种硬币计算数量(a)的变化方式的数量(N),通过加上: > 在没有第一种硬币的情况下,改变货币的方法(X)的数量。 改变(A-D)的方式(Y)的数量,其

  • 问题内容: java.util.Random源代码的第294行说 为什么是这样? 问题答案: 该描述并不完全准确,因为0不是2的幂。更好的说法是 当n是2的幂或2的幂的负数或零时。 如果n是2的幂,则二进制中的n是单个1,后跟零。-n为2的补数是倒数+ 1,因此位排成一行 要了解其工作原理,请将二进制补码视为逆+ 1。 因为当您添加一个得到两个的补码时,您会一直进行到一个。 如果n不是2的幂,则结

  • 这是uva问题的根源。在线法官。组织机构 这个问题基本上是说: 给定N笔必须给的钱!!我们需要找出我们能给多少最低硬币,以及这些硬币的总价值,这样使用n个给定面额给的额外金额就最小了! 例如: 我的问题是: 这里的重叠子问题是什么? 我的意思是: 有重叠的子问题吗<因为我找不到任何。。。

  • 问题内容: 在Java中,表达式为: 似乎等于: 尽管是有效的一元运算符,其优先级高于中的算术运算符。因此,编译器似乎假设该运算符不能为一元运算符,并解析该表达式。 但是,表达式: 即使存在以下唯一有效的解决方案,也不会编译: 和被指定为具有相同的优先级,那么为什么编译器为支持算术而解决看似模棱两可的问题,但为什么不这样做呢? 问题答案: 首先使用最大修改规则将文件标记化(转换为标记序列)-始终获

  • 问题内容: 我正在尝试计算给定日期的第n个工作日。例如,我应该能够计算给定日期的月份中的第三个星期三。 我已经编写了2个版本的函数,该代码可以做到这一点: 控制台输出 这两个函数中的逻辑显然是错误的,但是我似乎无法找到该错误-任何人都可以发现该代码出了什么问题-以及如何解决该问题以返回正确的值? 问题答案: 您的问题在这里: 首先,您用错误的方式减去东西:您需要从所需的日期减去实际的日期,而不是相

  • 问题内容: 问题是阿拉伯文字未打印-请谁能解决我的问题? 问题答案: 删除并将编码更改为,这应该使您的字符