泽肯道夫定理

249 阅读2分钟

泽肯道夫定理指出,**每个正整数都可以唯一地表示为一个或多个不同的非相邻或不连续的斐波那契数之和。**加起来等于N的斐波那契数的序列被称为N的泽肯道夫表示。

斐波那契数形成斐波那契数列,其中每个数字都是前面两个数字之和。序列的前两个项是0和1。
前20个斐波那契数是0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181.

该定理。设N是一个正整数。那么有一个唯一的递增序列(c_i)_i=0k(c\_{i})\_{i=0}^{k},其中(c_igeq2)(c\_{i} geq 2)
使得c_i+1>c_i+1forigeq0 c\_{i+1} > c\_{i}+1 for \\ i \\geq 0

$$N=\sum_{i=0}^{k}F_{c_{i}}$
这里F代表一个斐波那契数。这样一个斐波那契数的序列加起来有N个,被称为N的泽肯道夫表示。

例子

10的Zeckendorf表示是2+8。2+3+5的表示法不是泽肯道夫表示法,因为斐波那契数的顺序是连续的斐波那契数。

100的Zeckendorf表示法是89+8+3。

71的Zeckendorf表示法是55+13+3。

  1. N的泽肯道夫表示法可以通过减去不大于N的最大斐波那契数来找到,例如斐波那契数是N1。
  2. 如果这个结果不是0,就用不大于(N-N1)的最大斐波那契数,例如N2,来减去(N-N1)。
  3. 如果减去的结果是0,则找到了Zeckendorf表示法,否则重复进行,直到从余数中减去下一个最大的斐波那契数的结果是0,则找到了Zeckendorf表示法。
  4. 泽肯道夫表示法不应该包括两个连续的斐波那契数字。
  • 任何正整数的Zeckendorf表示都可以通过贪婪的算法找到,在算法的每个阶段都会选择最大的Fibonacci数字。

  • Zeckendorf表示不能由两个相邻或连续的斐波那契数组成。考虑F(1)是第一个斐波那契数,F(2)是第二个斐波那契数,F(N)是第N个斐波那契数,依此类推。

F(1) = 0, F(2) = 1, F(3) = 1, F(4) = 2, F(5) = 3, F(6) = 5.
We can see that F(5) + F(3) = 3 + 1 = 4
4 < 5                  (next Fibonacci number is 5)
F(6) = 5
F(5) + F(3) < F(6)
  • 如果我们假设到F(j-1)为止的非连续斐波那契数的总和都小于F(j)。
  • 同样地,到F(j)的总和将不包含F(j-1),并且是F(j)和到F(j-2)的非连续斐波那契数的总和,如上所述,该数小于F(j-1)。
  • 否则,F(j-1)将是比给定数小的最大斐波那契数,而不是F(j),即比给定数小的实际最大斐波那契数。
  • 因此,正数的Zeckendorf表示法是用非连续的斐波那契数来表示的。

程序

#include <iostream>

using namespace std;


int fitFibonacci(int N)
{   
    //first three terms of the Fibonacci sequence
    int p = 0, q = 1, r = 1;
    
    if(N == 0 || N == 1)
    return N;
    
    //finding the greatest Fibonacci number that is smaller than the number N.
    while(r <= N){
        p = q;
        q = r;
        r = p + q;
    }
    
    return q;
    
}

int main()
{
    int N = 111;
    cout << "Fibonacci representation of " << N << ": ";
    
    int rem = N ,num = 0;
    
    //greedy algorithm runs till the remainder is zero.
    while(rem > 0)
    {
       //finding the greatest Fibonacci number smaller than the given number. 
       num = fitFibonacci(rem);
       cout << num << " ";
       rem = rem - num;
    }
}

输出
111的斐波那契表示法:89 21 1

时间复杂度。 O(N * LogN)

负斐波那契数
负指数的斐波纳契数被称为负斐波纳契数。Negafibonacci数列的数字符合以下公式。

F_n=(1)n+1F_nF\_{-n} = (-1)^{n+1}F\_{n}

任何一个整数都可以被唯一地写成由不连续的负数组成的负数之和。

例子
-11 = f(-4) + f(-6) = (-3) + (-8)
11 = f(-7) + f(-4) + f(1) = 13 + (-3) + 1
25 = f(-9) + f(-6) + f(-2) = 34 + (-8) + (-1)

斐波那契编码

  • 一个数字的泽肯道夫表示法有一个特性,即该数字的二进制值不包含两个连续的1,因为该表示法永远不会有2个连续的斐波那契数字。
  • 斐波那契编码使用泽肯道夫表示法,将正整数编码为二进制代码词或二进制字符串。
  • 每个二进制字符串以 "11 "结尾,之前不包含任何其他 "11"。
  • 正整数的斐波那契码字是该整数的Zeckendorf表示法,其数字顺序相反,并在末尾附加一个 "1"。

例子
这里FC(N)代表数字N的斐波那契编码。
FC(65) = 0100100011
0100100011是65的斐波那契编码。

解码。
从左边开始,以2为起始指数,斐波那契编码中的1在3、6和19的位置。因此F(3)、F(6)和F(10)之和为65。

1×f(10) + 0×f(9) + 0×f(8)+ 0×f(7) + 1×f(6) + 0×f(5) + 0×f(4) + 1×f(3) + 0×f(2) = f(10) + f(6) + f(3)

F(10)+F(6)+F(3)=55+8+2=65

通过OpenGenus的这篇文章,你一定对泽肯道夫定理有了完整的认识。