算法-斐波那契数列_递归_递推_动态规划

算法-斐波那契数列_递归_递推_动态规划

问题概述


题目:斐波那契数列_递归_递推_动态规划

问题描述:
斐波那契数列是非常经典的算法问题,理解他的数学思想对我们程序猿编程有极大的帮助。

输入:
每个输入用例包含一个正整数n(0 <= n <= 30),你的目标是计算F(n);
输出:
可能有多组输入数据,对于每组输入数据,
输出一行,这一行输出F(n)的值;
样例输入:
1
样例输出:
1


1. 问题分析

斐波那契数列的关键就是推算他的表达式,自第二项开始,每一项都等于前两项之和,由此推得表达式:
F(1)=1;
F(2)=1;
F(n)=F(n-1)+F(n-2); (n >= 2)
对于递归方式来说,传入参数n,若n等于1或者等于0则直接返回值,若n大于等于2返回F(n - 1) + F(n - 2)的值即可;
对于递推方式来说,开辟一个有三个元素的整形数组存储,初始状态设置为前三项的值{0, 1, 1},后面每次根据 %3 得到的值选择某一个元素的位置替换,%3得到的那个点正好是我们之前计算结果得到的最初的那个值,也就是本次计算之后得到的值应取代的值的位置,递推结束之后,返回值即可;
对于动态规划方式,开辟一个比较大的整数型组存储我们已经计算出的F(n)值,这样便于后续计算。动态规划的思想是利用dp数组存储每一次我们计算得到的F(n)值,这样之后计算如果再用到这个值时就不需要递归或者递推去计算这个值了,因为我们的dp数组里已经保存了这个值,可以极大地提升计算速度,减少计算时间,而需要注意的点就是dp数组边界初始化为-1,这样便于我们计算dp数组以及直接返回计算过的F(n)的值,若dp[n]不等于-1说明这个F(n)我们已经计算过了,直接返回他的值,若不是则计算他的值,dp[n] = F(n - 1) + F(n - 2),最后返回这个dp[n]的值;
在三种方式中,动态规划方式记录了每一次的计算结果,对于大量数据来说处理时间最短,速度最快,递推次之,而递归稍显逊色最慢;
当然,如果只有几组数据,并且计算的数字都比较小,那么动态规划就不是最快的算法了,具体情况看遇到的算法题目来考虑应用吧!


1.1 算法核心

有关递斐波那契数列的数学知识,递归,递推,动态规划的编程思想;


2. 解决方案

递归

#include <iostream>
using namespace std;

int n, ans;
int Fibonacci(int n);

int main(void)
{
	while(scanf("%d", &n) != EOF)
	{
		ans = Fibonacci(n);
		printf("%d\n", ans);
	}

	return 0;
}

int Fibonacci(int n)
{
	if(n == 1 || n == 0) return n;
    else return Fibonacci(n - 1) + Fibonacci(n - 2);
}

递推

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

#define maxlength 1000

int n, ans;
int Fibonacci(int n);

int main(void)
{
	while (scanf("%d", &n) != EOF)
	{
		ans = Fibonacci(n);
		printf("%d\n", ans);
	}

	return 0;
}

int Fibonacci(int n)
{
	int t[3] = { 0, 1, 1 }, i; // 斐波那契数列前三项为0, 1, 1

	if (n > 2)
	{
		for (i = 3; i <= n; i++)
			t[i % 3] = t[(i + 1) % 3] + t[(i + 2) % 3];
		i--;
	}
	else
		i = n;

	return t[i % 3];
}

动态规划

#include <iostream>
using namespace std;

#define maxlength 1000

int dp[maxlength], n, ans;
int Fibonacci(int n);

int main(void)
{
	dp[0] = 0, dp[1] = 1;
	for(int i = 2; i <= n; i++)
			dp[i] = -1;
	while(scanf("%d", &n) != EOF)
	{
		ans = Fibonacci(n);
		printf("%d\n", ans);
	}

	return 0;
}

int Fibonacci(int n)
{
	if(dp[n] != -1)
		return dp[n];
	else
	{
		dp[n] = Fibonacci(n - 1) + Fibonacci(n - 2);
		return dp[n];
	}
}

3. 资源分享

旗木白哉のGitHub:
https://github.com/YangMengHeng
C++ / C源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/VSCode
Java源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/Java
旗木白哉のblog源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/%E6%97%97%E6%9C%A8%E7%99%BD%E5%93%89%E3%81%AEblog


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值