【发布时间】:2020-04-21 16:44:53
【问题描述】:
第n个三角形数定义为和1+2+...+n。我正在研究Project Euler problem 12,它要求找到具有超过 500 个除数的最小三角形数,因此(在 Python 中)我编写了两个函数,mytri(n) 和 mydiv(n),来计算第 n 个三角形数和数字n 的除数,分别。然后,我使用了一个循环,直到mydiv(mytri(n)) 大于或等于 500:
import math
def mytri(n):
return n*(n+1)/2
def mydivs(n):
num = 0
max = math.floor(n/2)
for k in range(1,max+1):
if n%k == 0:
num += 1
return num+1
n = 1
while (mydivs(mytri(n)) <= 500): n += 1
print(mytri(n))
我认为我写mytri() 和mydiv() 的效率很高,但根据一些测试,这个程序似乎很快就会变得笨拙。计算第一个有超过 100 个除数的数需要不到一秒,但计算第一个有超过 150 个除数的数大约需要 8-9 秒,这表明它可能是指数时间?我在计算复杂性或编写高效算法方面没有太多经验,但我曾经看到一个使用字典的示例(我认为是记忆化?)来极大地改进递归算法来计算斐波那契数,我想知道类似的想法是否可以在这里使用。
例如,第 n 个三角形数可以表示为 n(n+1)/2,因此不失一般性,它是奇数和偶数的乘积,分别为 n 和 (n+1)/2。如果您可以将每个数字的除数最多存储在字典中,那么您就不必在mydiv() 中重做计算,而只需引用字典即可。唯一的问题是找出 n 和 (n+1)/2 之间的哪些除数重叠以获得正确的数量。这是合理的进攻路线吗?还是我在这里遗漏了什么?
另外,我的算法的时间复杂度是多少,我将如何计算它?
【问题讨论】:
-
你不能真正使用任何内存,因为你总是使用其他 n。 (据我所知)。斐波那契之所以有效,是因为
F(n) = F(n-1) + F(n-2)它有一个递归,如果你计算F(50),你将计算F(30)多次,因此你可以使用内存。您可能应该从考虑另一种更有效的算法开始。 -
@goodatthis 检查我发布的答案。我可以帮你。
-
@goodatthis 如果对您有帮助,请接受答案。它将帮助整个社区确定正确的答案。
标签: python algorithm dynamic-programming