function F(n:Integer):Integer;
我认为第一个不可避免的步骤是做一个n个斐波那契数的数组,如下所示:
Fib[1]:=1;
Fib[2]:=1;
for i:=3 to n do
Fib[i]:=Fib[i-1]+Fib[i-2];
当然,我们可以通过只计算那些小于或等于n的斐波那契数来优化它,但这没有多大帮助,因为动态数组是不允许的。那么我们如何才能避免指数级的时间复杂度呢?
让我们来证明一些关于数字的东西:
引理1:设n≥1为整数,Fib(i)为最大Fibonacci数且Fib(i)≤n。然后,在n表示为具有不同指数的斐波那契数之和时,出现Fib(i)或Fib(i-1),但不是两者都出现。
证明:我们可以通过归纳法证明Fib(1)+Fib(2)+...+Fib(i-2)=Fib(i)-1之和。由于Fib(i)
function F(n : Integer, recurseHigh = True: Bool):
if n == 0: return 1
a, b = 1, 1
while a + b <= n:
a, b = b, a + b
res = 0
if recurseHigh: res += F(n - b)
res += F(n - a, n - a < a)
return res
F(0) = 1
F(1) = 2
F(2) = 2
F(3) = 3
F(4) = 3
F(5) = 3
F(6) = 4
F(7) = 3
F(8) = 4
F(9) = 5
F(10) = 4
F(11) = 5
F(12) = 4
F(13) = 4
F(14) = 6
F(4079078553298575003715036404948112232583483826150114126141906775660304738681982981114711241662261246) = 70875138187634460005150866420231716864000000
F(2093397132298013861818922996230028521104292633652443820564201469339117288431349400794759495467500744) = 157806495228764859558469497848542003200000000
F(1832962638825344364456510906608935117588449684478844475703210731222814604429713055795735059447061144) = 9556121706647393773891318116777984000000000
F(6529981124822323555642594388843027053160471595955101601272729237158412478312608142562647329142961542) = 7311968902691913059222356326906593280000000
F(3031139617090050615428607946661983338146903521304736547757088122017649742323928728412275969860093980) = 16200410965370556030391586130218188800000000
F(4787808019310723702107647550328703908551674469886971208491257565640200610624347175457519382346088080) = 7986384770542363809305167745746206720000000
F(568279248853026201557238405432647353484815906567776936304155013089292340520978607228915696160572347) = 213144111166298008572590523452227584000000000
F(7953857553962936439961076971832463917976466235413432258794084414322612186613216541515131230793180511) = 276031486797406622817346654015856836608000000
F(2724019577196318260962320594925520373472226823978772590344943295935004764155341943491062476123088637) = 155006702456719127405700915456167116800000000
F(4922026488474420417379924107498371752969733346340977075329964125801364261449011746275640792914985997) = 3611539307706585535227777776416785118003200
F(10^1000) = 1726698225267318906119107341755992908460082681412498622901372213247990324071889761112794235130300620075124162289430696248595221333809537338231776141120533748424614771724793270540367766223552120024230917898667149630483676495477354911576060816395737762381023625725682073094801703249961941588546705389069111632315001874553269267034143125999981126056382866927910912000000000000000000000000000000000000000000000000000000000000000000000000000000
更新:这里是Python代码:
memo = {}
def F(n, x=True):
if n == 0: return 1
if (n, x) in memo: return memo[n,x]
i = 1
a, b = 1, 1
while b + a <= n:
a, b = b, a + b
memo[n,x] = (F(n - b) if x else 0) + F(n - a, n - a < a)
return memo[n,x]
更新2:使用二分搜索查找i并使用快速矩阵求幂运算计算Fib(i),即使不需要记忆,也可以获得更好的运行时。但可能不值得这么做,特别是对于32位n。
更新3:为了好玩,这里有一个实现,可以证明它只做o(log n)
添加:
fib = [0,1]
def greedy(n):
while fib[-1] < n:
fib.append(fib[-1] + fib[-2])
i = 1
while fib[i+1] <= n: i += 1
digs = set()
while n:
while fib[i] > n: i -= 1
digs.add(i)
n -= fib[i]
return digs
def F(n):
digs = greedy(n)
top = max(digs)
dp = [[[0,0,0] for _ in xrange(4)] for _ in xrange(top+1)]
for j in xrange(0, 2): dp[0][j][0] = 1
for i in xrange(1, top + 1):
for j in xrange(0,2):
for k in xrange(0,j+1):
if i in digs:
dp[i][j][k] = dp[i-1][k+j][j] + dp[i-1][k+j+1][j+1]
else:
dp[i][j][k] = dp[i-1][k+j][j] + dp[i-1][k+j-1][j-1]
return dp[top][0][0]
主要内容:递归生成斐波那契数列,总结公元 1202 年,意大利数学家莱昂纳多·斐波那契提出了具备以下特征的数列: 前两个数的值分别为 0 、1 或者 1、1; 从第 3 个数字开始,它的值是前两个数字的和; 为了纪念他,人们将满足以上两个特征的数列称为斐波那契数列。 如下就是一个斐波那契数列: 1 1 2 3 5 8 13 21 34...... 下面的动画展示了斐波那契数列的生成过程: 图 1 斐波那契数列 很多编程题目要求我们输
题目链接 NowCoder 题目描述 求斐波那契数列的第 n 项,n <= 39。 <!--1}\end{array}\right." class="mathjax-pic"/> --> 解题思路 如果使用递归求解,会重复计算一些子问题。例如,计算 f(4) 需要计算 f(3) 和 f(2),计算 f(3) 需要计算 f(2) 和 f(1),可以看到 f(2) 被重复计算了。 递归是将一个问题划分
Python3 实例 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13,特别指出:第0项是0,第1项是第一个1。从第三项开始,每一项都等于前两项之和。 Python 实现斐波那契数列代码如下: 实例(Python 3.0+)# -*- coding: UTF-8 -*- # Filename : test.py # author by : www.runoob.com
问题内容: 我在Java世界中相对较新,遇到了一个我不明白的问题。 我有一堂课(去斐波那契行): 现在的任务是在单独的线程中分别启动f(x-1)和f(x-2)。一次实现Thread类,另一次实现Runnable。您可能知道,这是我教授的一项练习。 我知道如何在Java中启动线程,并且从理论上知道整个Thread的工作原理,但是我找不到在此递归函数中启动单独的线程的解决方案。 运行功能必须做什么?
本文向大家介绍JavaScript中的斐波那契数列,包括了JavaScript中的斐波那契数列的使用技巧和注意事项,需要的朋友参考一下 斐波那契数是这样的数,使得该序列中前两个后的每个数字都是前两个的和。该系列从1、1开始。示例- 我们可以编写一个程序来生成nth,如下所示: 您可以使用以下方式进行测试: 这将给出输出- 让我们看看这些函数调用实际上是如何发生的- 当我们调用f(5)时,我们将调用
一、题目 写一个函数,输入n,求斐波那契数列的第n项值。 斐波那契数列的定义如下: 二、解题思路 按照上述递推式,可以使用循环或递归的方式获取第n项式。 三、解题代码 public class Test { /** * 写一个函数,输入n,求斐波那契(Fibonacci) 数列的第n项 * @param n Fibonacci数的项数 * @ret