项目Euler31:了解程序解决方案

时间:2013-12-03 14:02:44

标签: python

我正在尝试了解我在论坛中找到的project euler #31解决方案。

问题是我们获得了具有以下价值的硬币:

coins=[1,2,5,10,20,50,100,200]

我们的任务是生成达到200的所有可能方式。例如,10 * 10 + 100 = 200将是一种可能的方式。

  1. 问题2:以下代码如何工作!与我的方法相比,它看起来非常优雅,简单和直接,运行速度更快。
  2. 当我浏览论坛时,我找到了这个解决方案:

    p_list = [1, 2, 5, 10, 20, 50, 100, 200]
    case_num = [1] + [0] * 200
    for i in p_list:
        for j in range(1, 201):
            if i <= j:
                case_num[j] += case_num[j-i]
    print case_num[200]
    

    第一行只是硬币值列表。第二行是创建一个数组,其中1后跟200 0。但接下来的四行让我感到困惑。我认为它正在增加数组中可能的方式的数量,所以case_num [200]将给出列表中的最后一个条目,但我不知道它是如何工作的。

1 个答案:

答案 0 :(得分:2)

正如你所说,这是一个非常好的解决方案。该代码通过1-200的每次迭代以每个硬币面额构建。

case_num数组最初由[1,0,0,0,0,0 ... 0,0,0]

组成

这些数字(除了最初的1)意味着你可以通过多少种方式建立到给定的总数(由...表示) 数字的索引)使用你到目前为止迭代过的p_list中的硬币。

p_list中的第一个硬币是1.因此,如果1可以放入索引中,那么您将获取上一个索引中的值并将其添加到当前索引中。这是有效的,因为如果有5种已知方法可以达到25并且你刚刚找到了大小为1的硬币,那么还有5种方法可以达到26 [前5种方法中的每一种都可以达到25] + 1硬币

所以在用1'迭代之后你会得到[1,1,1,1,1 ... 1,1]

现在你向上移动硬币。这次你使用的是2枚硬币。让我们再一次完成这个过程。如果2小于索引,那么您可以添加到当前索引的前一个索引的方法数。

例如2不适合索引1但是适合索引2.所以你刚刚创建了一个从0到2的新方法,所以你采取了所有你可以达到0的方法并将它们添加到你的目前的指数。在索引27上,2适合索引,因此你可以采用你可以达到25的方式并将它们添加到27,因为现在你已经拥有(所有这些方法可以获得25 + 1个2硬币)+(所有方式)在你知道你有2个大小的硬币之前你必须到27。

所以在用2的迭代之后你会得到[1,1,2,2,3,3,4,4 ......]

如果您仍然遇到问题,尝试浏览整个程序可能是值得的(可能会减少50个而不是200个)。