【发布时间】:2021-05-09 14:51:56
【问题描述】:
我正在浏览 Project Euler 编码存档并遇到问题 115,内容如下:
“注意:这是第 114 题的更难版本。
长度为 n 个单位的行具有最小长度的红色块 放置在其上的 m 个单位,使得任何两个红色块(它们是 允许是不同的长度)由至少一个黑色分隔 正方形。
让填充计数函数 F(m, n) 表示路数 可以填满一行。
例如,F(3, 29) = 673135 和 F(3, 30) = 1089155。
即对于m = 3,可以看出n = 30是最小值 填充计数函数首次超过一百万。
同理,对于m = 10,可以验证F(10, 56) = 880711 和 F(10, 57) = 1148904,所以 n = 57 是 填充计数功能首次超过一百万。
对于 m = 50,找到填充计数对应的 n 的最小值 功能首次突破百万。”
我可以使用蛮力方法(使用三个嵌套的 for 循环和中间的大量 while 循环,跨越大约 50 行代码)来解决这个问题。相比之下,我发现了这段代码,利用动态编程:
m, n = 50, 168
ways = [1]*(m) + [0]*(n-m+1)
for k in range(m, n+1):
ways[k] = ways[k-1] + sum(ways[:k-m]) + 1
ways[n]
现在这对我来说看起来很优雅!我了解代码的技术部分,但我不明白这段代码如何解决问题。希望在这里得到解释性帮助。
【问题讨论】:
-
你在哪里找到的,作者是谁,他们有解释吗?
-
问题 115 似乎很大程度上基于问题 114 的解决方案。以下是我找到的一些很好的解释:blog.dreamshire.com/project-euler-114-solution 和 mathblog.dk/project-euler-114-fill-row-with-blocks
-
感谢您的 cmets!这段代码的来源在第一个链接中给出,那里也有一些解释。我还是看不懂重点:/在发这篇文章之前,我也检查了其他链接。
标签: python dynamic-programming