斐波拉契数列=>多种方法的比较(分治、递归、动态规划/递推)
来源:互联网 发布:安卓原笔迹手写软件 编辑:程序博客网 时间:2024/04/28 21:52
斐波拉契数列是一个很不错的例子,它的第一项和第二项都为1,以后的每一项都是前两项的和。
这样,斐波拉契数列可以有很多种解法。
首先用递归:
//递归for斐波那契数列 #include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;long long work(int n){if(n==1||n==2){return 1;}else{return work(n-1)+work(n-2);}}int main(){int n;//freopen("fei.in","r",stdin);//freopen("fei.out","w",stdout);scanf("%d",&n);printf("%lld",work(n));return 0;}普通递归的方法存在很多的重复计算。效率自然很低。比如在算f(n-1)的时候,已经把f(n-2)算出来了,但是递归还要再算一次f(n-2)。
所以采用分治,一段一段计算,减少重复计算。
二分:
//二分分治for斐波那契 #include<cstdio>double n;int k;long long s,a;long long sishewuru(double g){if(g>=(int)g+0.5){return g+1;}else return g;}long long er(long long q){if(q==1||q==2){return 1;}else{return er(q-1)+er(q-2);}}long long wang(long long p){if(p==sishewuru(n/2)){return s;}if(p==sishewuru(n/2)-1){return a;}else return wang(p-1)+wang(p-2);}int main(){//freopen("fei.in","r",stdin);//freopen("fei.out","w",stdout);scanf("%lf",&n);s=er(sishewuru(n/2));a=er(sishewuru(n/2)-1);long long o=wang(n);printf("%lld",o);return 0;}二分效率也是极其有限的,普通递归大概算到40左右已经是极限,而二分可以算到75左右。
所以进一步拆分问题,使他重复得更少。
三分:
//三分分治for斐波那契数列 #include<cstdio>double n;int k;long long s,a;long long f,d;long long sishewuru(double g){if(g>=(int)g+0.5){return g+1;}else return g;}long long er(long long q){if(q==1||q==2){return 1;}else{return er(q-1)+er(q-2);}}long long wang(long long p){if(p==sishewuru(n/3)){return s;}if(p==sishewuru(n/3)-1){return a;}else return wang(p-1)+wang(p-2);}long long ring(long long i){if(i==sishewuru(2*n/3)){return f;}if(i==sishewuru(2*n/3-1)){return d;}else return ring(i-1)+ring(i-2);}int main(){//freopen("fei.in","r",stdin);//freopen("fei.out","w",stdout);scanf("%lf",&n);s=er(sishewuru(n/3));a=er(sishewuru(n/3)-1);f=wang(sishewuru(2*n/3));d=wang(sishewuru(2*n/3)-1);long long o=ring(n);printf("%lld",o);return 0;}三分已经可以在短时间内算出第110项左右了。接下来果断六分:
//六分分治for斐波那契数列 #include<cstdio>double n;int k;long long s,a;long long f,d;long long w,q,e,r,t,y;long long sishewuru(double g){if(g>=(int)g+0.5){return g+1;}else return g;}long long er(long long q){if(q==1||q==2){return 1;}else{return er(q-1)+er(q-2);}}long long wang(long long p){if(p==sishewuru(n/6)){return s;}if(p==sishewuru(n/6)-1){return a;}else return wang(p-1)+wang(p-2);}long long dao(long long x){if(x==sishewuru(n/3)){return f;}if(x==sishewuru(n/3-1)){return d;}else return dao(x-1)+dao(x-2);}long long yu(int v){if(v==sishewuru(n/2)){return w;}if(v==sishewuru(n/2-1)){return q;}else return yu(v-1)+yu(v-2);}long long nb(int m){if(m==sishewuru(2*n/3)){return r;}if(m==sishewuru(2*n/3-1)){return e;}else return nb(m-1)+nb(m-2);}long long ring(long long i){if(i==sishewuru(5*n/6)){return y;}if(i==sishewuru(5*n/6-1)){return t;}else return ring(i-1)+ring(i-2);}int main(){//freopen("fei.in","r",stdin);//freopen("fei.out","w",stdout);scanf("%lf",&n);s=er(sishewuru(n/6));a=er(sishewuru(n/6)-1);f=wang(sishewuru(n/3));d=wang(sishewuru(n/3)-1);w=dao(sishewuru(n/2));q=dao(sishewuru(n/2-1));r=yu(sishewuru(2*n/3));e=yu(sishewuru(2*n/3-1));y=nb(sishewuru(5*n/6));t=nb(sishewuru(5*n/6-1));long long o=ring(n);printf("%lld",o);return 0;}六分经测,可以短时间内算出200项左右,也许可以到210项。
由此发现,普通的递归可以到40左右,二分到75左右,三分110左右,六分200左右,可以看出,可以在短时间内算到的项数(n)与它分成多少段(r)成正比。
大概以40左右为系数。即:n=k*r.
但是这样的方法也是极其有限的,想要计算到后面,就要不断地扩大分段,很是麻烦。
所以可以直接利用递推,用动态规划算出来,效率会大大增强。
//递推/动态规划for斐波那契 #include<cstdio>long long a[10000];int main(){int n;//freopen("fei.in","r",stdin);//freopen("fei.out","w",stdout);scanf("%d",&n);a[1]=a[2]=1;for(int i=3;i<=n;i++){a[i]=a[i-1]+a[i-2];}printf("%lld",a[n]);return 0;}我定义了10000的整型数组,可以发现,这种方法计算10000项毫不费力。这样看来,这样的方法速度和效率都是非常高的。
斐波拉契数列 不同得解法还很多,这里不再列举。
1 0
- 斐波拉契数列=>多种方法的比较(分治、递归、动态规划/递推)
- 递归,递推,分治,贪心,动态规划......
- 斐波那契数列的多种算法,迭代法+递归法+动态规划+矩阵幂
- 斐波那契数列 递推 递归 备忘录 动态规划
- 数据结构(C#)--递归和动态规划法实现斐波那契数列的方法
- 整数划分 (递归、分治、动态规划)
- 数字三角形_递归_递推(动态规划)
- 石子归并 动态规划 递归&递推
- 递归+分治+贪心+动态规划
- 斐波拉契数列的递归、非递归、公式法多种方法实现
- 斐波那契数列的递归、递推算法比较
- 递归分治与动态规划--上台阶的问题
- 【递推】【动态规划】【数列】第二题 覆盖墙壁(wall.pas/c/cpp)
- 算法——动态规划(分治递归)
- 贪心、递归、递推以及动态规划算法的分析与对比(转:By: 夏天の冰块的BLOG)
- 贪心,递归,动态规划,及分治算法之间的区别和联系(二)
- 贪心,递归,动态规划,及分治算法之间的区别和联系(三)
- 贪心,递归,动态规划,及分治算法之间的区别和联系(四)
- Android面试题集锦(二)
- php 时间戳
- OpenWrt支持usb tethering
- Java Web中如何访问WEB-INF下的XML文件
- 设为首页代码和加入收藏JS代码(未测试)
- 斐波拉契数列=>多种方法的比较(分治、递归、动态规划/递推)
- HDU 2444 The Accomodation of Students(二分图判断+最大二分匹配)
- 写点日志--word 操作
- ROS by example- 第三章: 操作系统和ROS版本
- 安卓集成极光推送SDK基础服务
- HDU 5742 It's All In The Mind (水题)
- BufferedWriter/Reader and FileWriter/Reader
- 北斗系统基础知识1(北斗系统定位原理说明“图文详述”)
- 高仿微信抢红包动画特效