解释:有一个自然数x,它可以表示为两个自然数m和n(x=m*n)的乘积。接下来x,您需要用m+n-2(x=m+n-2) 替换。所有这一切都必须完成,直到x它变得平等1
x可能高达十亿
示例:程序收到数字 6。
6=3*2 3+2-2=3
6=6*1 6+1-2=5
3=3*1 3+1-2=2
5=5*1 5+1-2=4
2=2*1 2+1-2=1 - x=1, останавливаемся (до единицы мы дошли за 3 замены)
4=2*2 2+2-2=2
我的尝试
from math import sqrt
def isint(n):
return not(n%1)
def f(n):
count = 0
while(True):
x=sqrt(n)
if(n<=1):
return count
if(isint(x)):
n=x+x-2
else:
x=int(x)
while(isint(n/x)==False):
x=x-1
if(x<=0):
return count
n=int((n/x)+x-2)
count+=1
print('Минимальное кол-во попыток для числа 6 = ',f(6))
PS我的算法出错了,但还是算了一些数字
我不知道python...但是在C++中,这个问题的解决方案是:
如您所见,ideone在 0.04 秒内解决了 10 亿:)
关键点:
1.用裁剪搜索
2.从靠近根的值开始
3.记忆化
顺便说一句,最多一百万,最长的链是 11,所以显然你不应该期望深度递归。
您的算法是基于 if
a < b, then的假设f(a) <= f(b),但情况并非总是如此,例如f(7) = 4和f(8) = 3。首先,我认为值得从一个完整的枚举开始,如果你想不出更好的东西,那就添加 memoization。
以下是 C# 中完整递归迭代的简单示例:
如果需要对大于几百个的输入数字执行算法,那么记忆化是不可避免的,因为 完全枚举需要很长时间。下面是一个使用字典的例子:
内存消耗小,但执行速度显着提高。
这立即与缓存;-) 所以 Python 已经长大了))) 顺便说一下,f(1024) 给出 7。没有 @functools.lru_cache(),它需要 20 分钟,而使用 @functools.lru_cache() - 2 -3秒!!