[动态规划与回溯算法]斐波那契数列与变形

Posted 一个正直的男孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[动态规划与回溯算法]斐波那契数列与变形相关的知识,希望对你有一定的参考价值。

大家好这是我的一个新的专题,动态规划,这里有我大量学习DP(动归)的学习笔记,和我的见解,但是博主在这一块一个是一个小白,还在摸索如果有我那里有错误,或者有更好的思路请你在评论区留言


动态规划三加一准则

三:

状态定义

转移方程

定义初始状态


一:

数组(一维,二维)

其中比较难得的就是状态的定义和转移方程,一般把这俩个想明白定义出来,那么这个道题基本上可以算是写出来了。一般来说状态定义都是从问题中抽象出来的……

你或许好奇为啥要数组呢?

因为DP其实也是一个分治的算法(大问题化成小问题),DP一般都要把之前的子问题求出来的解保存起来,因为后面需要子问题的解去推导更大的子问题。如果我分解出来不用我分小问题的意义何在,一般来说是用数组来保存


斐波那契数列


题目描述:


分析:

很显然题目给了我们很多的信息,那么我们来看看如何把他抽象出来


状态定义:

题目告诉说 x 是由 x的前一项(x-1) + x的前前一项(x-2),那么我们就可以求第 i项 ,在用i的解去推 x ,所以我们需要一个数组去保存i项的解


状态初始化:

在题目中给给的分段函数可以看出x=1,x=2 时为一,那么这就是他的初始状态


递推方程:

题目其已经给我们写出来就是 fib(x-1)+fib(x-2),求当前一项需要知道前面俩项的结果

代码:

    int Fibonacci(int n) 
    
        if(n==0)//处理特殊情况
        
            return 0;
        
            
        //状态定义
        int * fib=new int[n+1];
        //状态初始化
        fib[1]=1;
        fib[2]=1;
        //转移方程
        for(int i=3;i<=n;i++)
        
            fib[i]=fib[i-1]+fib[i-2];
        
        
        //返回结果
       return  fib[n];
    
;

i项其实就是一个笼统的概念,其实需要好多个i项,就和之前一本书名字叫《5分钟学好英语》,内容也没错,知识5分钟学完之后你要花几千几万个5分钟进行复习……

上面的代码你看出哪里还有可以优化的地方嘛?

提示空间复杂度

……

……

……

……

……

我需要求第i项我是不是只需要知道 i-1 和 i-2 ,但是我不需要 知道 i-3……i-n 的值,那么我们可以用俩个变量进行动态更新

int Fibonacci(int n) 
    
        if(n==0)//处理特殊情况
        
            return 0;
        
            
        //状态定义 //状态初始化
         int third=1;
         int second=1;
         int frist=1;
       
        //转移方程
        for(int i=3;i<=n;i++)
        
          
            third=second+frist;
            //更新状态
            frist=second;
            second=third;
        
        
        //返回结果
       return third;
    
;


青蛙跳台阶


题目描述:


分析:

当青蛙跳到第n级台阶时,那么他要从哪里一级台阶跳上来呢?根据题目来看这应该不是火箭🐸,这只青蛙只可以跳 一层 或者 俩层 ,那只有俩种可能 就是在 n-1级的台阶 或 n-2级的台阶…………有没有很熟悉的感觉,这不就是披着羊皮的斐波那契嘛

那么我们就套用斐波那契的思路,从题中可以看出青蛙只有俩种跳法: 1级台阶 2级台阶

初始状态:

由图所示,初始状态就是 青蛙可以跳的台阶级数, x=1 是为1 x=2 时为2,但是题目中有一个反人类的操作就是当是第0层的时候青蛙也跳了一次,所以初始状态为 x=0 为1 x=1 为1


代码

int numWays(int n)
    
            
        //状态定义 //状态初始化
        int  third=1;
        int second=1;
        int frist=1;
       
        //转移方程
        for(int i=2;i<=n;i++)
        
            third=second+frist;
            frist=second;
            second=third;
        
        
        //返回结果
       return third;
    

唠唠家常

记住动态规三加一口诀,状态抽象,转移方程,状态初始化,与一个数组保存中间的解

以上是关于[动态规划与回溯算法]斐波那契数列与变形的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode日记——算法动态规划专题——斐波那契数列

算法题4 斐波那契数列

动态规划法从斐波那契数列谈起

动态规划法从斐波那契数列谈起

4.1 斐波那契系列问题的递归和动态规划

剑指offer-斐波那契数列