[动态规划与回溯算法]斐波那契数列与变形
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;
唠唠家常
记住动态规三加一口诀,状态抽象,转移方程,状态初始化,与一个数组保存中间的解
以上是关于[动态规划与回溯算法]斐波那契数列与变形的主要内容,如果未能解决你的问题,请参考以下文章