hdu - 1568 fibonacci
2013-08-05 20:09
369 查看
fibonacci是一个非常有趣的数列,中文翻译是“斐波那契”,我则妄称之为"肥婆纳妾",而对于肥婆纳妾我也是才刚刚接触,为什么说它有趣呢,当然不会是因为肥婆居然会纳妾啦,鄙人理由有四,
一. 有趣的兔子问题。若大家还记得中学的兔子问题,便会恍然大悟,原来自己和肥婆纳妾早已是老相识了,有道是白头如新,倾盖如故,便有这几分含味。
斐波那契在《算盘书》中提出了一个有趣的兔子问题:
一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔都不死,那么一年以后可以繁殖多少对兔子?
我们不妨拿新出生的一对小兔子分析一下:
第一个月小兔子没有繁殖能力,所以还是一对;
两个月后,生下一对小兔总数共有两对;
三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对;
……
依次类推可以列出下表:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/04/a71ab65e1f6e13d948b5e0a7cd8d9cad)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/04/b8004ffdad5b081b3557bc7b189896d1)
二.有趣的通项公式。这是一个用无理数来表示有理数的公式,又叫比内公式,也就是说fibonacci的通项公式叫比内公式(即肥婆纳妾的条件是比内裤~~oh my god!),这个公式将是做这道题的关键之一,公式如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201910/18/cd2d98f738033276e1c9a734c307fc76.jpg)
三.这肥婆居然和黄金分割有密切关系
有趣的是:这样一个完全是自然数的数列,通项公式却是用无理数来表达的。而且当n趋向于无穷大时,后一项与前一项的比值越来越逼近黄金分割0.618.(或者说后一项与前一项的比值小数部分越来越逼近黄金分割0.618、前一项与后一项的比值越来越逼近黄金分割0.618)
1÷1=1,2÷1=2,3÷2=1.5,5÷3=1.666...,8÷5=1.6,…………,89÷55=1.6181818…,…………233÷144=1.618055…75025÷46368=1.6180339889…...
越到后面,这些比值越接近黄金比.
四.自然界的fibonacci
斐波那契数列在自然科学的其他分支,有许多应用。例如,树木的生长,由于新生的枝条,往往需要一段“休息”时间,供自身生长,而后才能萌发新枝。所以,一株树苗在一段间隔,例如一年,以后长出一条新枝;第二年新枝“休息”,老枝依旧萌发;此后,老枝与“休息”过一年的枝同时萌发,当年生的新枝则次年“休息”。这样,一株树木各个年份的枝桠数,便构成斐波那契数列。这个规律,就是生物学上著名的“鲁德维格定律”。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/04/944e6a27d788ccd089bbf1337d3605fe)
这些植物懂得斐波那契数列吗?应该并非如此,它们只是按照自然的规律才进化成这样。这似乎是植物排列种子的“优化方式”,它能使所有种子具有差不多的大小却又疏密得当,不至于在圆心处挤了太多的种子而在圆周处却又稀稀拉拉。叶子的生长方式也是如此,对于许多植物来说,每片叶子从中轴附近生长出来,为了在生长的过程中一直都能最佳地利用空间(要考虑到叶子是一片一片逐渐地生长出来,而不是一下子同时出现的),每片叶子和前一片叶子之间的角度应该是222.5度,这个角度称为“黄金角度”,因为它和整个圆周360度之比是黄金分割数0.618033989……的倒数,而这种生长方式就决定了斐波那契螺旋的产生。向日葵的种子排列形成的斐波那契螺旋有时能达到89,甚至144条。
回归题目,看到a
= a[n - 1] + a[n - 2],大伙肯定想着用递归,可是递归对于0
<= n <= 100000000这么大的数就显得有心无力了,从效率来说,一般的递归要进行2^100000000次调用,不算时间上的耽搁,就连栈都会溢出,所以并不可用。记忆递归的话,只需进行100000000次调用即可,效率貌似解决得了,可是fibonacci增长速度极快,在n达到100之前就溢出了(_int64比int稍后而已),而题目只要求算前四位,这又让人想起了强大的log10(n)来,不得不说,假设一个数m,m = 10^lg(m),众所周知,一个数用科学计数法表示,可以写成a+10^b而10^b只是改变a的位权,对其数值并不影响,因此我们就等于把123456789这样的数转换成1.23456789来表示(就不用担心溢出了,但不能拿来四则运算,浮点数计算有误差!!),接下来,只要用好fibonacci的公式就好了,我们来化解一下公式(我看网上的化解法)对公式取log10,取完
后如下
![](https://oscdn.geek-share.com/Uploads/Images/Content/201910/18/aa0926c397a3d553643c855b509bf438.jpg)
此时我们分析题目,注意到两点
1.位数不大于四位的全部表示出来,而大于四位的则取其前四位。
2.当n越大时,取完log后的f(n)的最后一项越来越接近0,可以忽略不计,此时再用floor函数得到lg(f(n))的小数即可(10^1 = 10,小数的话就小于10,便是科学计数法的表示)
也就是说,在n < 21时,用记忆的递归就好了,在21以后就用公式,此时后项可忽略(n = 21时,答案才超过10000)
以下是个人代码:
一. 有趣的兔子问题。若大家还记得中学的兔子问题,便会恍然大悟,原来自己和肥婆纳妾早已是老相识了,有道是白头如新,倾盖如故,便有这几分含味。
斐波那契在《算盘书》中提出了一个有趣的兔子问题:
一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔都不死,那么一年以后可以繁殖多少对兔子?
我们不妨拿新出生的一对小兔子分析一下:
第一个月小兔子没有繁殖能力,所以还是一对;
两个月后,生下一对小兔总数共有两对;
三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对;
……
依次类推可以列出下表:
二.有趣的通项公式。这是一个用无理数来表示有理数的公式,又叫比内公式,也就是说fibonacci的通项公式叫比内公式(即肥婆纳妾的条件是比内裤~~oh my god!),这个公式将是做这道题的关键之一,公式如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201910/18/cd2d98f738033276e1c9a734c307fc76.jpg)
三.这肥婆居然和黄金分割有密切关系
有趣的是:这样一个完全是自然数的数列,通项公式却是用无理数来表达的。而且当n趋向于无穷大时,后一项与前一项的比值越来越逼近黄金分割0.618.(或者说后一项与前一项的比值小数部分越来越逼近黄金分割0.618、前一项与后一项的比值越来越逼近黄金分割0.618)
1÷1=1,2÷1=2,3÷2=1.5,5÷3=1.666...,8÷5=1.6,…………,89÷55=1.6181818…,…………233÷144=1.618055…75025÷46368=1.6180339889…...
越到后面,这些比值越接近黄金比.
四.自然界的fibonacci
斐波那契数列在自然科学的其他分支,有许多应用。例如,树木的生长,由于新生的枝条,往往需要一段“休息”时间,供自身生长,而后才能萌发新枝。所以,一株树苗在一段间隔,例如一年,以后长出一条新枝;第二年新枝“休息”,老枝依旧萌发;此后,老枝与“休息”过一年的枝同时萌发,当年生的新枝则次年“休息”。这样,一株树木各个年份的枝桠数,便构成斐波那契数列。这个规律,就是生物学上著名的“鲁德维格定律”。
这些植物懂得斐波那契数列吗?应该并非如此,它们只是按照自然的规律才进化成这样。这似乎是植物排列种子的“优化方式”,它能使所有种子具有差不多的大小却又疏密得当,不至于在圆心处挤了太多的种子而在圆周处却又稀稀拉拉。叶子的生长方式也是如此,对于许多植物来说,每片叶子从中轴附近生长出来,为了在生长的过程中一直都能最佳地利用空间(要考虑到叶子是一片一片逐渐地生长出来,而不是一下子同时出现的),每片叶子和前一片叶子之间的角度应该是222.5度,这个角度称为“黄金角度”,因为它和整个圆周360度之比是黄金分割数0.618033989……的倒数,而这种生长方式就决定了斐波那契螺旋的产生。向日葵的种子排列形成的斐波那契螺旋有时能达到89,甚至144条。
回归题目,看到a
= a[n - 1] + a[n - 2],大伙肯定想着用递归,可是递归对于0
<= n <= 100000000这么大的数就显得有心无力了,从效率来说,一般的递归要进行2^100000000次调用,不算时间上的耽搁,就连栈都会溢出,所以并不可用。记忆递归的话,只需进行100000000次调用即可,效率貌似解决得了,可是fibonacci增长速度极快,在n达到100之前就溢出了(_int64比int稍后而已),而题目只要求算前四位,这又让人想起了强大的log10(n)来,不得不说,假设一个数m,m = 10^lg(m),众所周知,一个数用科学计数法表示,可以写成a+10^b而10^b只是改变a的位权,对其数值并不影响,因此我们就等于把123456789这样的数转换成1.23456789来表示(就不用担心溢出了,但不能拿来四则运算,浮点数计算有误差!!),接下来,只要用好fibonacci的公式就好了,我们来化解一下公式(我看网上的化解法)对公式取log10,取完
后如下
![](https://oscdn.geek-share.com/Uploads/Images/Content/201910/18/aa0926c397a3d553643c855b509bf438.jpg)
此时我们分析题目,注意到两点
1.位数不大于四位的全部表示出来,而大于四位的则取其前四位。
2.当n越大时,取完log后的f(n)的最后一项越来越接近0,可以忽略不计,此时再用floor函数得到lg(f(n))的小数即可(10^1 = 10,小数的话就小于10,便是科学计数法的表示)
也就是说,在n < 21时,用记忆的递归就好了,在21以后就用公式,此时后项可忽略(n = 21时,答案才超过10000)
以下是个人代码:
#include<stdio.h> #include<cmath> int shu[10000]; int fibonacci(int n) { if(shu > 0) return shu ; if(n == 0 || n == 1) return n; else return shu = fibonacci(n - 1) + fibonacci(n - 2); } int main() { int n; shu[0] = 0; shu[1] = 1; while(scanf("%d",&n) == 1) { if(n < 21) printf("%d\n",fibonacci(n)); else { double m; m =(-0.5)*log10(5.0) + n * log10(((1.0 + sqrt(5.0))/2.0)); m = m - floor(m); m = pow(10.0,m); while(m < 1000) m *= 10; printf("%d\n",(int)m); } } return 0; }
相关文章推荐
- HDU 1568 Fibonacci
- 【HDU】-1568-Fibonacci(公式+log取小数)
- hdu 1568 Fibonacci 对数。。
- HDU 1568 Fibonacci(斐波那契前四位)
- HDU 1568 Fibonacci
- HDU-1568-Fibonacci【求高位数字】
- hdu 1568 Fibonacci
- hdu 1568 Fibonacci
- HDU 1568 Fibonacci(科学计数法+对数)
- hdu 1568 Fibonacci(fibonacci通项+对数性质)
- HDU-1568 Fibonacci
- HDU 1568 Fibonacci
- hdu-1568 Fibonacci
- [斐波那契前n位 数学技巧] HDU 1568 Fibonacci
- hdu 1568 Fibonacci
- hdu 1568 Fibonacci
- HDU 1568 Fibonacci
- HDU 1568 Fibonacci
- HDU 1568 Fibonacci
- HDU-1568 Fibonacci【数学公式题】