新年啥也不会,就随便生个兔子吧

135 阅读1分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

一道经典的算法题:

有一对兔子,从出生后第三个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子。若兔子都不死,问第n (n为正整数) 个月的兔子对数为多少?

先来推导一下它的规律:

12345678
可生育兔子对数00112358
兔子总对数1123581321

有没有发现可生育兔子对数在三月之后会和两月前兔子总对数对齐。原因很简单,即兔子三月后每月都会生小兔子。

且三月后,总兔子 = 上月兔子 + 当月可生育兔子,

当月可生育兔子 = 两月前兔子,

总兔子 = 上月兔子 + 两月前兔子。

 

假设月份为n,n>0

n≤2,F(n) = 1

n>2,F(n) = F(n-1) + F(n-2)

数列从第3项开始,每一项都等于前两项之和。这就是斐波那契数列 (Fibonacci sequence)。

 

代码实现:

用递归其实是非常直观的,只需要算出最后需要多少F(1) + F(2) 就行了,

比如F(5),

F(5) = F(4) + F(3)

= [F(3) + F(2)] + [F(2) + F(1)]

= {[F(2) + F(1)] + F(2)} + [F(2) + F(1)]

public static int sum(int n) {  
    if (n < 1)  
        return 0;  
    if (n < 3)  
        return 1;  
    return sum(n - 1) + sum(n - 2);  
}

递归算法虽然写起来简单易懂,但是随着月份增长,调用次数也大幅度增加,浪费内存空间、效率较低。

那么这时可以对其做一点改变,从逆向运算改为正向。从前面的推论可以发现,整个兔子繁殖过程可以简化为涉及三个变量,即F(n)、F(n-1)、F(n-2) ,在代码中也可以用三个变量存储兔子对数值,并在计算出当月兔子后,将月份里的兔子对数往后移,并赋给空闲的两个变量。

public static int sum(int n) {  
    if(n < 1)  
        return 0;  
    if(n < 3)  
        return 1;  
    int f1 = 1; //上上月兔  
    int f2 = 1; //上月兔  
    int f3 = 2;  
    for(int i = 3; i < n; i++) {  
        f1 = f2;  
        f2 = f3;  
        f3 = f1 + f2; //当月兔  
    }  
    return f3;  
}

最后用我贫瘠的前端知识发了一个码上掘金代码块。

斐波那契数列在计算机科学、数学和生物学等领域有着广泛的应用。在计算机科学中,斐波那契数列被用来实现高效的算法,例如求解最长公共子序列问题。在数学中,斐波那契数列可以用来表示数列的渐进复杂度,也可以用来解决递推问题。在生物学中,斐波那契数列可以用来模拟生物繁殖的过程。

总的来说,斐波那契数列是一种有趣且有用的数学模型,在许多领域都有着广泛的应用。

如果能给我一对这样的兔子就好了,到时候可以卖出好多兔子

祝大家兔年财源滚滚,money就像兔子生兔子一样