ACM/ICPC算法训练 之 数学很重要—斐波拉契●卢卡斯数列(HNNUOJ 11589)

  



  看到这个标题,貌似很高大上的样子= =,其实这个也是大家熟悉的东西,先给大家科普一下斐波拉契数列

  • 斐波拉契数列

    又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……

    在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)

    在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

  • 斐波拉契数列与黄金分割-----(涉及今天的例题)

    有趣的是:这样一个完全是自然数的数列,通项公式却是用无理数来表达的。而且当n趋向于无穷大时,前一项与后一项的比值越来越逼近黄金分割0.618.(或者说后一项与前一项的比值小数部分越来越逼近黄金分割0.618、前一项与后一项的比值越来越逼近黄金分割0.618)

    1÷1=1,1÷2=0.5,2÷3=0.666...,3÷5=0.6,5÷8=0.625,…………,55÷89=0.617977…,…………144÷233=0.618025…46368÷75025=0.6180339886…...

    越到后面,这些比值越接近黄金比.

  • 斐波拉契数列-部分数学规律

          奇数项求和

          偶数项求和

          平方求和


  以下正式入题啦~

  • 斐波拉契-卢卡斯数列

    卢卡斯数列1、3、4、7、11、18…,也具有斐波那契数列同样的性质。(我们可称之为斐波那契—卢卡斯递推:从第三项开始,每一项都等于前两项之和f(n) = f(n-1)+ f(n-2)。

    这两个数列还有一种特殊的联系(如下表所示),F(n)*L(n)=F(2n),及L(n)=F(n-1)+F(n+1)


n

1

2

3

4

5

6

7

8

9

10


斐波那契数列F(n)

1

1

2

3

5

8

13

21

34

55


卢卡斯数列L(n)

1

3

4

7

11

18

29

47

76

123


F(n)*L(n)

1

3

8

21

55

144

377

987

2584

6765

    类似的数列还有无限多个,我们称之为斐波那契—卢卡斯数列

    如1,4,5,9,14,23…,因为1,4开头,可记作F[1,4],斐波那契数列就是F[1,1],卢卡斯数列就是F[1,3],斐波那契—卢卡斯数列就是F[a,b]。

    

  • 与斐波拉契数列的另一个共同性质:  
  • 中间项的平方数与前后两项之积的差的绝对值是一个恒值

    斐波那契数列:|1*1-1*2|=|2*2-1*3|=|3*3-2*5|=|5*5-3*8|=|8*8-5*13|=…=1

    卢卡斯数列:|3*3-1*4|=|4*4-3*7|=…=5

    F[1,4]数列:|4*4-1*5|=11

    F[2,5]数列:|5*5-2*7|=11

    F[2,7]数列:|7*7-2*9|=31

  • 黄金特征-----(与例题有关)

    斐波那契数列这个值是1最小,也就是前后项之比接近黄金比例最快,我们称为黄金特征

    黄金特征1的数列只有斐波那契数列,是独生数列。卢卡斯数列的黄金特征是5,也是独生数列。

    前两项互质的独生数列只有斐波那契数列和卢卡斯数列这两个数列。


  应用例题:

    

    

    题意:大致就是给定一个斐波拉契-卢卡斯数列中的某一项an(题目没有说明,但是这其实就是斐波拉契卢卡斯数列),然后让你求出初始的斐波拉契-卢卡斯数列a1和a2的值,并使得a2尽可能小。

    我用的是数学规律的思路

  • 在一个斐波拉契-卢卡斯数列的无穷大项(记为第m项),则第m-1项除以m项一定无限接近黄金分割0.618---可以计算倒数第二项的模糊值(设为a)
  • 且m足够大时,(m-1)/m>=0.618
  • 需要注意:在m值较大时,(m-1)/m即便很接近0.618,但m值太大,因此0.618*m得到的模糊值也会有较大误差,所以需要a++直到找到最适合的前两项
  • 上一点注意的详细公式是:小于两倍的sqrt(n)。
 1 //斐波拉契-卢卡斯数列
 2 //Memory 1100 K,Time: 234 Ms
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8
 9 #define INF 0x3f3f3f3f
10
11 int m1,m2;    //让第二项最小的初始两项
12
13 //计算初始两项并刷新最适合的m1,m2
14 void compute(int a,int b,int t)
15 {
16     while(t <= a && t >= 1)
17     {
18         b = a;
19         a = t;
20         t = b - a;
21     }
22     if(m2 > b)
23     {
24         m1 = a;
25         m2 = b;
26     }
27 }
28
29 int main()
30 {
31     int T,n;
32     scanf("%d",&T);
33
34     while(T--)
35     {
36         int a,t;
37         scanf("%d",&n);
38         a = (int)(0.618*n)-1;    //倒数第二项模糊值
39
40         m1 = m2 = INF;
41         int i = -1;
42         while(a+(++i) <= n && i <= (int)2*sqrt(n))    //倒数第二项小于最后一项,且次数小于2*sqrt(n)
43         {
44             compute(a+i,n,n-a-i);
45         }
46
47         printf("%d %d\n",m1,m2);
48     }
49
50     return 0;
51 }

  上述Code的 i <= (int)2*sqrt(n)的不等式是小编试出来的,测试数据在这些次数内可以过,如果不加的话,肯定是TLE的。

  大家如果有更加合适的Code可以写在评论里面(⊙o⊙)哦~,小编太渣了,没有更加清楚明白的思路= =

  Fighting~


时间: 2024-10-19 20:45:27

ACM/ICPC算法训练 之 数学很重要—斐波拉契●卢卡斯数列(HNNUOJ 11589)的相关文章

ACM/ICPC算法训练 之 数学很重要-浅谈“排列计数” (DP题-POJ1037)

这一题是最近在看Coursera的<算法与设计>的公开课时看到的一道较难的DP例题,之所以写下来,一方面是因为DP的状态我想了很久才想明白,所以借此记录,另一方面是看到这一题有运用到 排列计数 的方法,虽然排列计数的思路简单,但却是算法中一个数学优化的点睛之笔. Poj1037  A decorative fence 题意:有K组数据(1~100),每组数据给出总木棒数N(1~20)和一个排列数C(64位整型范围内),N个木棒长度各异,按照以下条件排列,并将所有可能结果进行字典序排序 1.每一

ACM/ICPC算法训练 之 数学很重要-平面几何(POJ 1269)

题意:给定四点的坐标(x,y),分别确定两直线,求出其交点,若重合or平行则输出相应信息 用四个点的坐标算出直线通式(ax+by+c=0)中的a,b,c,然后利用a,b,c计算出交点坐标(其他公式不够通用= =,比如斜率限制) 我利用两次平行判定重合 公式利用 初高中数学知识或代数知识 在草纸上仔细推导出来= =,让a,b,c为整数,比如可以演算得到a = y2-y1,b = x1-x2这一类公式. 详细Code如下: 1 //给定四点,分别确定两直线,求出其交点,若重合or平行则输出相应信息

ACM/ICPC算法训练 之 数学问题

好歹我是数学专业的学生,还是要写写训练的时候遇到的数学问题滴~~ 在ACM集训的时候在各高校OJ上也遇见过挺多的数学问题,例如大数的处理,素数的各种算法,几何问题,函数问题(单调,周期等性质),甚至是各种数学定理或公式的变形.其实算法本身也属于数学研究的范畴(计算机本就是数学的衍生嘛),诸如众多排序算法,搜索算法也是许多精巧的数学逻辑思维,所以大家学计算机千万别忽视数学这门基础学科啊. 貌似说了好多废话= =||,待小编进入正题,今天在湖大OJ训练赛上看到一道数学题,话不多说,直接上图! ___

剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调用的层级太多,就会超出栈容量. 循环:通过设置计算的初始值及终止条件,在一个范围内重复运算. 斐波拉契数列 题目一:写一个函数,输入n,求斐波拉契(Fibonacci)数列的第n项,定义如下: 第一种解法:用递归的算法: long long Fabonacci(unsigned int n) { i

经典算法___斐波拉契数列

分享一段斐波拉契数列的例子,不过我对算法没怎么接触过,只能写出最简单,最基本的 def fibs(num):     result = [0,1]         #斐波拉契数列初始变量          for i in range(num-2):      #循环,因为上边已经有两个变量,所以-2              result.append(result[-2] + result[-1])       #吧倒数第一项与倒数第二项相加作为最后一项的值              ret

算法导论第十九章 斐波那契堆

<算法导论>第二版中在讨论斐波那契堆之前还讨论了二项堆,但是第三版中已经把这块的内容放到思考题中,究极原因我想大概是二项堆只是个引子,目的是为了引出斐波那契堆,便于理解,而且许多经典的算法实现都是基于斐波那契堆,譬如计算最小生成树问题和寻找单源最短路径问题等,此时再把二项堆单独作为一章来讲显然没有必要.类似的堆结构还有很多,如左倾堆,斜堆,二项堆等,下次我打算开一篇博客来记录下它们的异同点. 一.摊还分析(第十七章) 这些高级的数据结构的性能分析一般是基于一个技术——摊还分析,可以理解成一种时

有序表查找算法(折半,插值,斐波那契)

今天总结了有序表查找常用的三种算法与大家分享. 1.折半查找折半查找又称二分查找,它的基本思想是:在有序表中,取中间记录作为比较对象,若相等则查找成功:若给定值小于中间记录的关键字,则在中间记录左半区继续查找,若给定值大于中间值,则在又半区寻找,不断重复以上过程. 算法代码(java版) int binarySearch(int[] a,int key){ int low,high,mid; low = 0; high = a.length-1; while(low<=high){ mid =

P1-2017级算法第一次上机 A 水水的斐波那契数列

题目描述 相信大家都学过斐波那契数列,虽然很简单,但是斐波那契数列却是很重要的哦,那么让我们来复习一下斐波那契数列吧! 输入 多组数据输入 每行一个整数n (0<n<=30) 输出 对于每组数据,输出一行,为斐波那契数列第n 项的值 输入样例 1 2 3 4 输出样例 1 1 2 3 思路 用一个一维数组f(n)来表示斐波那契数列第n项的值. 则根据定义,后一项等于前两项之和,很容易得到:f(n) = f(n-1) + f(n-2). 有两种做法,递归和循环. 虽然很多人都说递归好理解,但是作

ACM/ICPC算法训练 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是: 给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤. 所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题就是找出从初状态到目标状态所经过的一系列中间状态.八数码问题一