幼儿园:从斐波那契数列开始

这是通往幼儿园的车,佬请主动下车右转!


目录

引子

深度优先搜索

从记忆化搜索到动态规划

滚动数组优化

尾声


引子

        很久很久以前,我们的小斐波那契养了一对小兔子,哦,这两只贪吃的小兔子在某个阳光明媚的早晨,不小心吃了一株基因突变的大白菜而发生了基因突变,于是乎这两只小兔子及其后代获得了以下能力:
        1、永生
        2、繁殖周期固定,且一次繁殖只能生出一对小兔子,与此同时小兔子出生后的第一周期不具备繁殖能力

        也就是说第一周期小兔子没有繁殖能力,所以还是一对;第二周期生下一对小兔于是共有两对小兔;第三周期老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对……
        小斐波那契因为没有作业,闲的没事干,于是开始无聊地数兔子,他发现,兔子对数按周期数呈这样一个数列:1、1、2、3、5……聪明的小斐波那契自然也发现了数列的规律:前面相邻两项之和,构成了后一项。小斐波那契十分高兴,他决定将数列用自己的名字命名,于是乎著名的“斐波那契数列”诞生了,它具有以下美妙而简单的性质:
1、a_{n}+a_{n+1}=a_{n+2}
2、\lim_{n \to \infty }\frac{a_{n}}{a_{n+1}}=\frac{\sqrt{5}-1}{2}


深度优先搜索

        一不小心小斐波那契到了上高中的年纪,他的小兔子在家里生了一窝又一窝,每次回到家小斐波那契都很苦恼:因为兔子繁殖的速度超过了他学算数的速度,他已经数不清自己家里有多少对兔子了,但是他还记得小兔子已经繁殖了多少周期,他想请你教教他,算算自己家里究竟有了多少对兔子,这决定着小兔子们的死活——究竟是被吃掉,还是被吃掉。

#include<bits/stdc++.h>
using namespace std;
int dfs(int x){
	if(x==1) return 1;
	else if(x==2) return 1;
	return dfs(x-1)+dfs(x-2);
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%d",dfs(n));
	return 0;
} 

        小斐波那契十分高兴,因为算出来的结果显示小斐波那契的家足够容纳更多的小兔子,所以他决定暂时不吃掉这些小兔子,直到有一天——


从记忆化搜索到动态规划

        小斐波那契发现输入繁殖周期后,自己的电脑计算小兔子的数量需要很久,经过细细推敲,小斐波那契发现重复的、多余的搜索占用了大量的时间,比如:

        小斐波那契不想让这些重复的搜索占用自己和兔兔玩耍的时间,他决定更新你的代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int dfs(int x){
	if(x==1) return 1;
	else if(x==2) return 1;
	if(!a[x]) a[x]=dfs(x-1)+dfs(x-2);
	return a[x];
}
int main(){
	memset(a,0,sizeof(a));
	int n;
	scanf("%d",&n);
	printf("%d",dfs(n));
	return 0;
} 

        这样子小斐波那契就不用花很多时间在电脑前等结果,而是有很多多余的时间和小兔子玩耍了,不过小斐波那契依然觉得自己的代码不够精简,于是又思考了两天,代码3.0出炉了:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N];
int main(){
	memset(a,0,sizeof(a));
	a[1]=1;a[2]=1;
	scanf("%d",&n);
	for(int i=3;i<=n;i++) a[i]=a[i-1]+a[i-2];
	printf("%d",a[n]);
	return 0;
} 

滚动数组优化

        经过两次优化,小斐波那契对3.0代码十分满意,不过,追求十全十美的小斐波那契仍然觉得代码有一定的优化空间,譬如……空间复杂度?

#include<bits/stdc++.h>
using namespace std;
int n,a[5];
int main(){
	memset(a,0,sizeof(a));
	a[1]=1;a[2]=1;
	scanf("%d",&n);
	for(int i=3;i<=n;i++){
		a[3]=a[1]+a[2];
		a[1]=a[2];
		a[2]=a[3];
	}
	printf("%d",a[3]);
	return 0;
} 

尾声

萧炎和纳兰家的三年之约如期而至又过了三年,小斐波那契从高中毕业啦,小兔子也繁殖了六十个周期,毕竟人到了18岁,就不能过得像个小孩子,小斐波那契决定忍痛杀死自己那养了三年的1548008755920只小兔子,请全世界人民吃烤全兔,那么你觉得平均每个人能分到多少多少只兔子呢?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值