Fibonacci Numbers is posed by Fibonacci in 13th century.
Fibonacci Numbers 是源自“孤岛上的兔子”问题,问题是这样的:在孤岛上被放了两只刚刚生下来的兔子(一公一母),兔子到了第2个月就能够生小兔子了,且每个月生一对小兔子。
设$f(n)$表示第n个月开始时有多少对兔子,$f(n)=f(n-1)+f(n-2)$,其中f(n-1)表示上个月的那些兔子,f(n-2)表示在n-2个月开始时已经有的兔子,他们到了第n个月时一定有生育能力,因此会在第n个月开始时生下f(n-2)对兔子。
开始时,f(1)=1,f(2)=1。
递推关系:
\[fib(n)=\left\{ \begin{array}{ll} fib(n-1)+fib(n-2) & n \ge 3 \\ 1 & n=1,2 \end{array}\right.\]
动态规划方法:
1 f[1]=1; 2 f[2]=1; 3 for(int i=3;i<=n;i++) 4 f[i]=f[i-1]+f[i-2]; 5 return f[n];
效率:$O(n)$
其实我们还能够通过另外一个更加巧妙的方法在 $O(1)$ 时间内解Fibonacci Numbers。
由于$f_n=f_{n-1}+f_{n-2}$,特征方程为 $r^n=r^{n-1}+r^{n-2}$,即 $r^2=r+1$,解得 $r=\frac{1+\sqrt{5}}{2}\mbox{或}r=\frac{1-\sqrt{5}}{2}$,因此$f_n=\alpha_1\left(\frac{1+\sqrt{5}}{2}\right)^n+\alpha_2\left(\frac{1-\sqrt{5}}{2}\right)^n$,根据$f_1=1$和$f_0=0$得$\alpha_1=\frac{1}{\sqrt{5}},\alpha_2=-\frac{1}{\sqrt{5}}$,因此:
\[f_n=\frac{1}{\sqrt{5}}\left(\frac{1+\sqrt{5}}{2}\right)^n-\frac{1}{\sqrt{5}}\left(\frac{1-\sqrt{5}}{2}\right)^n\]
比如$f_8=\frac{1}{\sqrt{5}}\left(\frac{1+\sqrt{5}}{2}\right)^8-\frac{1}{\sqrt{5}}\left(\frac{1-\sqrt{5}}{2}\right)^8$=21。
虽然这个方法看起来能够在$O(1)$内做完,但是需要复杂的乘法,速度不见得真的快。