• 算法与数据结构---6.5、斐波那契数列-递归解法


    算法与数据结构---6.5、斐波那契数列-递归解法

    一、总结

    一句话总结:

    递推法的递推表达式就是递归的各个元素之间的关系,所以递推表达式明确之后,递归的代码也就特别好写了
    #include <iostream>
    using namespace std;
    const int mod=1000000007;
    
    int find(int n){
       if(n==1||n==2) return 1;
       else{
           return (find(n-1)+find(n-2))%mod;
       }
    }
    
    int main(){
        int n;
        cin>>n;
        cout<<find(n)<<endl;
        return 0;
    }

    二、斐波那契数列

    博客对应课程的视频位置:6.5、斐波那契数列-递归解法
    https://www.fanrenyi.com/video/27/277

    1、题目描述

    问题描述:

    满足F1=F2=1,F(n)=F(n-1)+F(n-2)的数列称为斐波那契数列(Fibonacci),
    它的前若干项是1,1,2,3,5,8,13,21,34,55...,求此数列第n项 mod 10^9+7的值(n>=3)。

    输入格式:
    一行一个正整数n

    输出格式:
    一行一个整数表示答案。

    输入输出样例:
    输入5,输出5
    输入10,输出55

    【数据范围】
    对于60%的数据,1<=n<=92;
    对于100%的数据,1<=n<2^63。


    题目位置:
    P1962 斐波那契数列 - 洛谷 | 计算机科学教育新生态
    https://www.luogu.com.cn/problem/P1962

    2、递推解法

     1 /*
     2 
     3 递推关系式:
     4 题目中已经非常明显的给出了,就是
     5 F(n)=F(n-1)+F(n-2)
     6 
     7 解决递推问题的一般步骤
     8 1、建立递推关系式:F(n)=F(n-1)+F(n-2)
     9 2、确定边界条件:
    10 f(1)=f(2)=1,
    11 所以我们的循环可以从3开始,到n结束,
    12 也就是3-n
    13 
    14 算法步骤:
    15 1、确定初始值
    16 2、循环做递推,3-n
    17 
    18 */
    19 #include <iostream>
    20 using namespace std;
    21 const int mod=1000000007;
    22 int f[200000];
    23 int main(){
    24     int n;
    25     cin>>n;
    26     //1、确定初始值
    27     f[1]=f[2]=1;
    28     //2、循环做递推,3-n
    29     for(int i=3;i<=n;i++){
    30         //F(n)=F(n-1)+F(n-2)
    31         f[i]=(f[i-1]+f[i-2])%mod;
    32     }
    33     cout<<f[n]<<endl;
    34     return 0;
    35 }

    3、滚动数组优化

     1 /*
     2 
     3 之前的最大子段和的动态规划的优化的时候,
     4 我们讲了滚动数组优化,
     5 原因是 对应的状态转移方程为:
     6 f[i]=max(f[i-1]+a[i],a[i]) (2<=i<=n)
     7 里面只用到了f[i]和f[i-1]这两个元素,
     8 所以可以用只有两个元素的数组来优化
     9 
    10 我们现在的递推表达式是:
    11 f[i]=f[i-1]+f[i-2] (3<=i<=n)
    12 里面用到了f[i]、f[i-1]和f[i-2]三个元素,
    13 所以可以用含有三个元素的数组来优化
    14 
    15 滚动数组的代码修改也很简单
    16 直接在递推表达式有i的位置%3即可
    17 f[i%3]=f[(i-1)%3]+f[(i-2)%3];
    18 (%3是因为现在是有三个元素的滚动数组)
    19 
    20 注意:
    21 取结果的时候,n也需要模3,例如f[n%3]
    22 
    23 */
    24 
    25 #include <iostream>
    26 using namespace std;
    27 const int mod=1000000007;
    28 int f[3];
    29 int main(){
    30     int n;
    31     cin>>n;
    32     //1、确定初始值
    33     f[1]=f[2]=1;
    34     //2、循环做递推,3-n
    35     for(int i=3;i<=n;i++){
    36         //F(n)=F(n-1)+F(n-2)
    37         f[i%3]=(f[(i-1)%3]+f[(i-2)%3])%mod;
    38     }
    39     //注意n也需要模3
    40     cout<<f[n%3]<<endl;
    41     return 0;
    42 }

    4、递推和动态规划的关系

    /*
    
    上述代码也就是这个题目动态规划的写法
    
    动态规划里面有状态,状态转移方程
    递推里面初始值,递推表达式
    其实动态规划里面的状态转移方程,就是递推表达式
    动态规划里面的初始状态,就是递推里面的初始值
    
    所以动态规划可以看做是一种特殊的递推,
    动态规划可以看做保存中间状态(中间结果)的递推
    
    对于这题:
    状态可以设置为:f[i]为 斐波那契数列第n项 mod 10^9+7的值
    那么状态转移方程就是递推表达式:F(n)=F(n-1)+F(n-2)
    初始状态:f[1]=f[2]=1
    
    */

    5、三个变量解法

     1 /*
     2 f[3] 可以直接用3个变量a、b、c来代替
     3 这个时候就不能通过取模来自动变换位置了
     4 
     5 
     6 */
     7 #include <iostream>
     8 using namespace std;
     9 const int mod=1000000007;
    10 int main(){
    11     int n;
    12     int a,b,c;
    13     cin>>n;
    14     //1、确定初始值
    15     //这里对a也赋值为1,是为了保证n=1和n=2的时候也有正确结果输出
    16     c=a=b=1;
    17     //2、循环做递推,3-n
    18     for(int i=3;i<=n;i++){
    19         //F(n)=F(n-1)+F(n-2)
    20         c=(b+a)%mod;
    21         //保留f(n)和f(n-1)做下一轮的f(n-1)和f(n-2)
    22         a=b;
    23         b=c;
    24     }
    25     cout<<c<<endl;
    26     return 0;
    27 }

    6、递归写法

     1 /*
     2 
     3 本题递推法的递推的关系式非常明确,就是f[i]=f[i-1]+f[i-2]
     4 递推法的递推关系式,对应到递归,就是递归的各个元素之间的关系
     5 明确这个,递归的代码就特别好敲
     6 
     7 递归注意点
     8 递归的终止条件:n=2和n=1
     9 递归的递推表达式:f[i]=f[i-1]+f[i-2] (3<=i<=n)
    10 递归的返回值:所求值(斐波那契数列第n项 mod 10^9+7的值)
    11 
    12 */
    13 #include <iostream>
    14 using namespace std;
    15 const int mod=1000000007;
    16 
    17 int find(int n){
    18    if(n==1||n==2) return 1;
    19    else{
    20        return (find(n-1)+find(n-2))%mod;
    21    }
    22 }
    23 
    24 int main(){
    25     int n;
    26     cin>>n;
    27     cout<<find(n)<<endl;
    28     return 0;
    29 }

     
  • 相关阅读:
    flex布局语法
    sqlserver判断text字段是否有数据
    z-index设置后导致遮罩层显示跳动问题
    C# UpdatePanel加载完毕回调JS
    json日期字符串格式化时间
    钉钉考勤机开发需要注意的一个坑
    python bs4 + requests4 简单爬虫
    温故而知新: 关于 js Form 方式提交的一些新认知
    window 环境 Composer 安装 thinkphp5
    百度地图 绘制东莞东城地图示例
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13053454.html
Copyright © 2020-2023  润新知