项目Euler 31:为什么这个解决方案有效?

时间:2015-02-08 06:17:36

标签: algorithm

我一直在研究项目欧拉问题#31的各种解决方案:

  

在英格兰,货币由英镑,英镑和便士,p和   一般流通有八个硬币:1p,2p,5p,10p,20p,   50便士,1英镑(100便士)和2英镑(200便士)。

     

可以通过以下方式赚取2英镑:1x£1 + 1x50p + 2x20p + 1x5p + 1x2p + 3x1p

     

使用任意数量的硬币可以使用多少种不同的方式?

我很困惑为什么这个特殊的暴力解决方案有效(source):

int target  = 200;
int ways = 0;

for (int a = target; a >= 0; a -= 200) {
    for (int b = a; b >= 0; b -= 100) {
        for (int c = b; c >= 0; c -= 50) {
            for (int d = c; d >= 0; d -= 20) {
                for (int e = d; e >= 0; e -= 10) {
                    for (int f = e; f >= 0; f -= 5) {
                        for (int g = f; g >= 0; g -= 2) {
                            ways++;
                        }
                    }
                }
            }
        }
    }
}

基于这个解决方案,我希望在最里面的级别还有一个嵌套的for循环,递减1,对于1p值的硬币。

例如,我们何时计算200p仅由1p硬币组成的情景?

目前,代码会得到正确的答案。但如果添加一个额外的for循环,那么答案似乎应该更大。我错过了什么?

2 个答案:

答案 0 :(得分:3)

因为for循环计算出一个数字<= 200的方法,假设剩余部分由1p硬币组成。例如,考虑第一次迭代,其中a = b = c = d = e = f = g = 200,这正是您明确询问的情况,其中200p由所有1组成。

答案 1 :(得分:0)

对于2p,5p,10p,20p,50p,£1(100p)和£2(200p)硬币的任何给定组合,总计高达2英镑或更少,正好有一个1p硬币组成一个甚至2英镑。因此,您不需要另一个循环来迭代1p硬币的数量。