【发布时间】:2012-08-24 20:07:40
【问题描述】:
也许我误读了这个问题。对于那些不熟悉Project Euler's Problem 31 的人,这里有问题:
调查英国货币面额的组合。
在英格兰,货币由英镑、英镑和便士组成,一般流通的硬币有八种:
1p、2p、5p、10p、20p、50p、1 英镑 (100p) 和 2 英镑 (200p)。
可以通过以下方式赚取 2 英镑:
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
使用任意数量的硬币可以通过多少种不同的方式制作 2 英镑?
我明白这怎么可能是一个动态编程问题,但我忍不住走捷径:
为了解决这个问题,我分解了使用 1p、1p 和 2p 以及 1p、2p 和 5p 硬币可以制作 1 到 6 便士的方法。
仅使用一美分硬币
- 1 个组合
- 1p
- 1 个组合
- 2×1p
- 1 个组合
- 3×1p
- 1 个组合
- 4×1p
- 1 个组合
- 5×1p
- 1 个组合
- 6×1p
仅使用一便士和两便士硬币
- 1 个组合
- 1p
- 2 种组合
- 2p
- 2×1p
- 2 种组合
- 2p + 1p
- 3×1p
- 3 种组合
- 2×2p
- 2p + 2×1p
- 4×1p
- 3 种组合
- 2×2p + 1p
- 2p + 3×1p
- 5×1p
- 4 种组合
- 3×2p
- 2×2p + 2×1p
- 2p + 4×2p
- 6×2p
仅使用一便士、两便士和五便士硬币
- 1 个组合
- 1p
- 2 种组合
- 2p
- 2×1p
- 2 种组合
- 2p + 1p
- 3×1p
- 3 种组合
- 2×2p
- 2p + 2×1p
- 4×1p
- 4 种组合
- 5p
- 2×2p + 1p
- 2p + 3×1p
- 5×1p
- 5 种组合
- 5p + 1p
- 3×2p
- 2×2p + 2×1p
- 2p + 4×2p
- 6×2p
我注意到这种疯狂是有规律的。显然,最多只有一种方法可以仅用一种硬币获得所需的“余额”。对于这个问题的情况,没有必要考虑一分钱。因此,仅使用一美分硬币,只有一种方法可以获得任何非负余额。请注意,只有一种方法可以获得零余额:没有硬币。
快速浏览了一下,我注意到第二个示例中的模式。可能组合的数量等于 n / 2 加 1 的商,其中 n 是任何非负整数。在 Python(我编写解决方案时使用的语言)中,如下所示:
n // 2 + 1
我注意到+ 1 正在为特定“目标余额”添加上一个示例的结果。巧合?可能是。但看了第三个例子后,我很快注意到可能的组合数量如下:
n // 5 + n // 2 + 1
我实现了这个模式,它将占所有八个硬币:
n // 200 + n // 100 + n // 50 + n // 20 + n // 10 + n // 5 + n // 2 + 1
n 设置为 200,我推断答案是 178。这个数字对我来说是有意义的,不过,我不会自己编写所有可能的组合。然而,Project Euler 指出这是不正确的。
我在网上查到正确的解法是73682。
所以我想问你,仍在阅读的 Stack Overflow 用户,我的推理中的谬误在哪里?
【问题讨论】:
-
我不确定我是否可以解释哪里出了问题,但你的公式不适用于 n >= 7。
-
@Blckknght,你问的很有趣。不,当
n为 7 时,输出为 5。但是,我发现答案实际上是 6。也许我的逻辑只是巧合地适用于给定的示例?我也刚刚确认它不适用于 8、9 或 10。
标签: python algorithm dynamic-programming combinatorics