zoukankan      html  css  js  c++  java
  • 斐波那契序列 集锦

    [定理1] 标准Fibonacci序列(即第0项为0,第1项为1的序列)当N大于1时,一定有f(N)和f(N-1)互质

    其实,结合“互质”的定义,和一个很经典的算法就可以轻松证明
    对,就是辗转相除法
    互质的定义就是最大公约数为1

    数学归纳法是很有用的证明方法,我们接下来这个定理用数学归纳法就很好证明:
    [定理2]若i为奇数, f(i)*f(i)=f(i-1)*f(i+1)+1,否则f(i)*f(i)=f(i-1)*f(i+1)-1
    对,这个定理用数学归纳法可以轻松证明,大家有兴趣可以自己尝试

    [定理3] f(n)=f(i)*f(n-i-1)+f(i+1)*f(n-i)

    f(n)=f(1)*f(n-2)+ f(2)*f(n-1)
        =f(2)*f(n-3)+ f(3)*f(n-2)
        =f(3)*f(n-4)+ f(4)*f(n-3)
    看来没有错,证明方法就是这样

    这个公式也可以用来计算较大的fibonacci数除以某个数的余数

    设i=n/2 不过,为了保证计算能延续下去 需要每次保留三个值
    这样,下一次计算就可以利用这三个值来求出两个值,再相加就可以得到第三个值
    譬如,计算出f(5),f(6),f(7),可以计算出f(11)、f(12),然后推出f(13)
    就是刚才洛奇的悲鸣(364738334)所提到的矩阵方法
    我们知道我们若要简单计算f(n),有一种方法就是先保存
    a=f(0),b=f(1),然后每次设:
    a'=b b'=a+b

    并用新的a'和b'来继续这一运算

    如果大家熟悉利用“矩阵”这一工具的话,就知道,如果把a、b写成一个向量[a,b],完成上述操作相当于乘以矩阵
    0 1
    1 1
    也就是说,如果我们要求第100个fibonacci数,只需要将矩阵
    [0,1]乘上
    0 1
    1 1
    的一百次方,再取出第一项

    因为我们知道,矩阵运算满足结合律,一次次右乘那个矩阵完全可以用乘上那个矩阵的N次方代替,更进一步,那个矩阵的N次方就是这样的形式:
    f(n-1) f(n)
    f(n) f(n+1)

    而求矩阵的N次方,由于矩阵乘法满足结合律,所以我们可以用log(N)的算法求出——这个算法大家都会么?
    一个是二分,一个是基于二进制的求幂

    二分的原理:要求矩阵的N次方A(N),设i=N/2若N%2==1, 则 A(N)=A(i)*A(i)*A(1)若N%2==0, 则 A(N)=A(i)*A(i)

    基于二进制的原理:将N拆为二进制数,譬如13=1101那么 A^13= A^8 * A^4 * A^1 (这里^表示幂运算)

    也就是说,由A^1开始,自乘得到A^2,然后自乘得到A^4,如果N对应位为1,则将这个结果乘到目标上去

    这样的话,将所有乘法改为模乘,就可以得到一个较大Fibonacci数除以M的余数

    若不用递归,其实类似

    http://acm.pku.edu.cn/JudgeOnline/problem?id=3070
    这里用的fib矩阵略有不同,是
    f(n+1) f(n)
    f(n) f(n-1)
    但实际上可以验证效果是一样的

    这题是要求求F(n)的最后四位数,所有乘法过程增加一个模10000的步骤即可,大家可以收藏稍候AC

    关于矩阵我们告一段落,等下会回来继续探讨利用矩阵来解决复杂些的Fibonacci问题

    http://acm.hdu.edu.cn/showproblem.php?pid=1568
    我们来看这题,这题要求求出Fibonacci某项的前四位

    当然,用矩阵也可以解决这道题——只要将乘法改为乘并保留前四位

    我们采用double 保留整数部分四位 这题最好还是double吧

    不过显然有更好的解法——如果我们知道Fibonacci序列的通项公式

    F(n) = (((1+Sqrt(5))/2)^n - ((1-Sqrt(5))/2)^n)*1/Sqrt(5)

    不过组合数学里也有这一公式的推导方法 叫做“线性齐次递推式”

    这个解法的核心是,通解是某个数的幂 将f(n)=x^n代入递推方程,可以解出三个通解 0和 (1+sqrt(5))/2

    通常把“0”称作平凡解,那么特解就是通解的某个线性组合

    再代入f(0)=0 f(1)=1,就可以得出我们刚才的公式

    不过通常情况下,我们只需要记住那个公式就可以了

    提醒大家,记忆公式的时候千万别忘记了系数1/sqrt(5)

    因为(1-sqrt(5))/2的绝对值小于1

    所以当i较大的时候,往往可以忽略掉这一项
    f(i)≈((1+Sqrt(5))/2)^n/sqrt(5);

    所以,刚才列举出的HDOJ的1568,可以很简单的30以内直接求解,30以上采用这个公式,还是用log(N)求幂的算法求解
    恩,就是公式的前半部分

    http://acm.hdu.edu.cn/showproblem.php?pid=1021
    http://acm.zju.edu.cn/show_problem.php?pid=2060
    Fibonacci某项是否被3整除

    [定理5] 标准Fibonacci序列对任意大于2的正整数的余数序列,必然是以“0 1”为循环节开头的序列

    显然0、1是序列开头,也就是说序列开头就是循环节开头

    循环长度的计算貌似是个比较难的问题,我一时还没有想到有效解法,不过,要说明的是,计算复杂度时,这个循环节长度应该按复杂度O(N^2)计算

    恩,证明方法是利用同余定理、反证法,还有我们之前证明过的相邻项一定互质的定理,留给大家家庭作业

    http://acm.hdu.edu.cn/showproblem.php?pid=1588
    这是前天比赛关于Fibonacci的一道题,大家先看看题。
    Description看后半部分就行了

    现在告诉大家一种正确解法,然后大家就可以去搞定这道题向别人炫耀了

    首先,我们将问题整理一下,就是对等差数列 ai=k*i+b,求所有的f(ai)之和除以M的余数

    当0<=i<N

    大家有没有想到,因为ai是等差数列,倘若f(ai)也是个等什么序列,那说不定就有公式求了

    f(ai)显然不是等差数列,直接看上去也不是等比数列

    但是如果把f(ai)换成我们刚才所说的Fibonacci矩阵呢?

    是的,可是我们对矩阵是直接求幂即可,由于矩阵加法的性质,我们要求A^ai的右上角元素之和,只要求A^ai之和的右上角元素

    就矩阵这个东西来说,完全可以看作一个等比数列,
    首项是:A^b
    公比是:A^k
    项数是:N

    呵呵,我们可以把问题进一步简化

    因为矩阵的加法对乘法也符合分配律,我们提出一个A^b来,形成这样的式子:
    A^b*( I + A^k + (A^k)^2 + .... + (A^k)^(N-1) )

    A^b 和 A^k 显然都可以用我们之前说过的方法计算出来,这剩下一部分累加怎么解决呢

    简单起见,设A^k=B
    要求 G(N)=I + ... + B^(N-1),设i=N/2
    若N为偶数,G(N)=G(i)+G(i)*B^i
    若N为奇数,G(N)=I+ G(i)*B + G(i) * (B^(i+1))

    呵呵,这个方法就是比赛当时ACRush用的
    而农夫用的则是更精妙的方法,大家可想知道

    我们来设置这样一个矩阵
    B I
    O I
    其中O是零矩阵,I是单位矩阵

    将它乘方,得到
    B^2 I+B
    O   I
    乘三方,得到
    B^3 I+B+B^2
    O   I
    乘四方,得到
    B^4 I+B+B^2+B^3
    O   I

    既然已经转换成矩阵的幂了,继续用我们的二分或者二进制法,直接求出幂就可以了

    http://online-judge.uva.es/p/v110/11089.html
    大家来读读这一题

    Fibinary数是指没有相邻的两个1的二进制数。给N,求出第N大的Fibinary数

    相对于二进制中每一位的值是2的幂,十进制中每一位的值是十的幂,
    Fibonacci进制是每一位的值是对应Fibonacci数的一种计数系统。
         8 5 3 2 1
    1     1
    2     1 0
    3     1 0 0
    4     1 0 1
    5     1 0 0 0
    6     1 0 0 1
    7     1 0 1 0
    8     1 0 0 0 0
    9     1 0 0 0 1
    10   1 0 0 1 0
    11   1 0 1 0 0
    12   1 0 1 0 1
    以上是前12个数字对应的十进制到Fibonacci进制的表格

    Fibonacci的运算方法很奇怪。首先,它每一位上非0即1,而且不同于二进制的逢二进一或者十进制的逢十进一,它的进位方法是逢连续两个1,则进1

    譬如
    1010110==> 1011000 ==> 1100000==>10000000

    在最低位有个特殊情况,最低位既可以逢2进1,也可以和次低位一起逢相邻进1
    这种奇怪的进位方法,换句话描述就是,不存在两个连续的1
    因为Fibonacci数其实也增长很快,int范围内好像只有46个,本题只需要用最简单的办法转换成Fibonacii进制即可
    其中一题是
    http://www.mydrs.org/program/down/ahoi2004day1.pdf
    中的第二题,叫做数字迷阵
    还有一题是PKU上的很出名的取石子问题
    http://acm.pku.edu.cn/JudgeOnline/problem?id=1067

    这题相当复杂,大家可以自己思考,往Fibonacci上想,也可以阅读这里的论文:
    http://episte.math.ntu.edu.tw/articles/mm/mm_03_2_02/index.html
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2967

    另外这题 可以利用Fibonacci判断数据范围进行优化设计。不过貌似可以水过去,仅仅给大家提供个思路罢

    关于Fibonacci和黄金分割,还有很多更高明的结论和定理,希望大家也继续讨论,将自己的知识和他人共享
    http://episte.math.ntu.edu.tw/articles/mm/mm_02_4_10/index.html
    中例3详细讲述了用生成函数来计算Fibonacci数公式的运算过程。http://acm.hdu.edu.cn/showproblem.php?pid=1568
    Fibonacci 求fibonacci前4位

    http://acm.hdu.edu.cn/showproblem.php?pid=1588
    Gauss Fibonacci
    http://acm.pku.edu.cn/JudgeOnline/problem?id=1067
    取石子问题
    http://episte.math.ntu.edu.tw/articles/mm/mm_03_2_02/index.html 是报告
    http://acm.pku.edu.cn/JudgeOnline/problem?id=3070
    Fibonacci矩阵
    http://acm.hdu.edu.cn/showproblem.php?pid=1021

    http://acm.zju.edu.cn/show_problem.php?pid=2060
    Fibonacci某项是否被3整除
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2116
    Fibonacci进制计算
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2967
    利用Fibonacci判断数据范围进行优化设计。
    http://online-judge.uva.es/p/v110/11089.html
    Fi-binary numbers,Fibonacci进制。
    http://www.mydrs.org/program/down/ahoi2004day1.pdf
    第二题 数字迷阵   这些,是今天涉及到的资料和网页

  • 相关阅读:
    HDU 5938 Four Operations 【贪心】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5935 Car 【模拟】 (2016年中国大学生程序设计竞赛(杭州))
    HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5933 ArcSoft's Office Rearrangement 【模拟】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5929 Basic Data Structure 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)
    【转】LaTeX 符号命令大全
    HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)
    HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)
    数据结构之稀疏矩阵
    C++中引用(&)的用法和应用实例
  • 原文地址:https://www.cnblogs.com/Knuth/p/1559951.html
Copyright © 2011-2022 走看看