Rosalind: 兔子与递归

简介: 问题描述序列 指的是一组对象的集合,其中允许重复。序列分为有限序列和无限序列两种类型,我们通常用 表示序列中的第n个对象。递归其实就是当前的序列依赖于之前的序列。

问题描述

序列 指的是一组对象的集合,其中允许重复。序列分为有限序列和无限序列两种类型,我们通常用 a_n 表示序列中的第n个对象。

递归其实就是当前的序列依赖于之前的序列。最典型的案例就是兔子繁衍问题,假设一开始第一个月有1对兔子(A),到了第二个月这对兔子(A)性成熟,到了第三个月这对兔子(A)生出了一对兔子(B)。到了第四个月兔子(A)又生了一对兔子(D),之前刚的兔子(B)性成熟。到了第五个月,兔子(A)又生了兔子E,兔子(B)生出了兔子(F),而兔子(D)性成熟。

当然一图胜过千言万语,也就是下面这个情况

兔子繁衍图

这也就是斐波那契数列,公式为

F_n = F_{n-1} + F_{n-2}

现在,如果每个具有繁衍能力的兔子能够生出k对兔子,那么n个月后一共有多少对兔子?

结题思路

新的斐波那契数列如下:

F_n = F_{n-1} + K \times F_{n-2}

第一版递归代码如下:

#include <stdio.h>
#include <stdlib.h>

long int FIB(long int n, long int k)
{
    if (n == 1 || n == 2){
        return 1;
    } else{
        return FIB(n-1,k) + k * FIB(n-2, k);
    }

}

int main(int argc, char *argv[])
{
    if (argc != 3){
        printf("USAGE: ./FIB n k \n");
        return 1;
    }
    long int n = atoi(argv[1]);
    long int k = atoi(argv[2]);
    printf("month is %ld, %ld rabbit pairs per \n", n, k);
    long total = FIB(n,k);
    printf("The total number of rabbit is %ld \n", total);
    return 0;

}

注意,这个数字增长的很快,所以用了long int

上面的方法在month很大的时候时候,这些迭代算法的由于会反复求解一些重复的子问题,导致求解速度就会非常慢,比如求解第100个月会有多少个兔子,会需要很久很久。而且很容易导致栈溢出,解决方案就是**动态规划**dynamic programming

动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc != 2){
        printf("USAGE: ./FIBv2 n k \n");
    }

    long int n = atoi(argv[1]);
    long int k = atoi(argv[2]);

    long int month[n-1];
    int i = 0;
    for (i = 0 ; i < n; i++){
        if ( i == 0 || i == 1){
            month[i] = 1;
        } else{
            month[i] = month[i-1] + k * month[i-2];
        }
    }

    printf("After %ld month, there are %ld rabbits\n", n, month[n-1]); 
   

    return 0;
}

这个代码在求解第100个月有多少兔子的时候,基本上是秒答。

目录
相关文章
|
8月前
|
算法
算法刷题(二十二):宝石与石头
算法刷题(二十二):宝石与石头
79 0
|
JavaScript 前端开发 Python
leetcode每日一题 2021/4/4 781. 森林中的兔子
leetcode每日一题 2021/4/4 781. 森林中的兔子
70 0
|
6月前
【蓝桥杯】[递归]母牛的故事
蓝桥杯——[递归]母牛的故事
79 1
【蓝桥杯】[递归]母牛的故事
|
8月前
|
机器学习/深度学习 算法 C++
【动态规划】C++算法:403.青蛙过河
【动态规划】C++算法:403.青蛙过河
|
8月前
【每日一题Day230】LC2611老鼠和奶酪 | 排序+贪心
【每日一题Day230】LC2611老鼠和奶酪 | 排序+贪心
75 0
【洛谷算法题】B2029-大象喝水【入门1顺序结构】
【洛谷算法题】B2029-大象喝水【入门1顺序结构】
|
存储 人工智能 测试技术
第十四届蓝桥杯省赛JavaB组试题E【蜗牛】Dijkstra堆优化 or 线性DP?
第十四届蓝桥杯省赛JavaB组试题E【蜗牛】Dijkstra堆优化 or 线性DP?
152 0
第十四届蓝桥杯省赛JavaB组试题E【蜗牛】Dijkstra堆优化 or 线性DP?
PTA猴子选大王(约瑟夫环问题)
PTA猴子选大王(约瑟夫环问题)
142 1
|
机器学习/深度学习
大臣的旅费-动规/深搜
大臣的旅费-动规/深搜
88 0
|
算法 JavaScript 前端开发
日拱算法,森林中的兔子问题
森林中有未知数量的兔子。提问其中若干只兔子 "还有多少只兔子与你(指被提问的兔子)颜色相同?" ,将答案收集到一个整数数组 answers 中,其中 answers[i] 是第 i 只兔子的回答。

热门文章

最新文章

相关实验场景

更多