📜  策肯多夫定理(非邻近斐波那契表示)

📅  最后修改于: 2021-05-04 20:43:06             🧑  作者: Mango

Zeckendorf定理指出,每个正整数都可以唯一地写为不同的非相邻斐波那契数之和。如果两个斐波那契数在斐波那契数列(0、1、1、2、3、5 ..)中一个接一个,则是邻居。例如,3和5是邻居,但2和5不是邻居。

给定一个数字,找到作为非连续斐波纳契数之和的数字表示形式。
例子:

Input:  n = 10
Output: 8 2
8 and 2 are two non-consecutive Fibonacci Numbers
and sum of them is 10.

Input:  n = 30
Output: 21 8 1
21, 8 and 1 are non-consecutive Fibonacci Numbers
and sum of them is 30.

强烈建议您最小化浏览器,然后自己尝试。
这个想法是使用贪婪算法。

1) Let n be input number

2) While n >= 0
     a) Find the greatest Fibonacci Number smaller than n.
        Let this number be 'f'.  Print 'f'
     b) n = n - f 
C++
// C++ program for Zeckendorf's theorem. It finds
// representation of n as sum of
// non-neighbouring Fibonacci Numbers.
#include 
using namespace std;
 
// Returns the greatest Fibonacci Numberr smaller than
// or equal to n.
int nearestSmallerEqFib(int n)
{
    // Corner cases
    if (n == 0 || n == 1)
        return n;
 
    // Find the greatest Fibonacci Number smaller
    // than n.
    int f1 = 0, f2 = 1, f3 = 1;
    while (f3 <= n)
    {
        f1 = f2;
        f2 = f3;
        f3 = f1 + f2;
    }
    return f2;
}
 
// Prints Fibonacci Representation of n using
// greedy algorithm
void printFibRepresntation(int n)
{
    while (n > 0)
    {
        // Find the greates Fibonacci Number smaller
        // than or equal to n
        int f = nearestSmallerEqFib(n);
 
        // Print the found fibonacci number
        cout << f << " ";
 
        // Reduce n
        n = n - f;
    }
}
 
// Driver code
int main()
{
    int n = 30;
    cout << "Non-neighbouring Fibonacci Representation of "
         << n << " is \n";
    printFibRepresntation(n);
    return 0;
}


Java
// Java program for Zeckendorf's theorem. It finds
// representation of n as sum of non-neighbouring
// Fibonacci Numbers.
class GFG {
    public static int nearestSmallerEqFib(int n)
    {
        // Corner cases
        if (n == 0 || n == 1)
            return n;
 
        // Find the greatest Fibonacci Number smaller
        // than n.
        int f1 = 0, f2 = 1, f3 = 1;
        while (f3 <= n) {
            f1 = f2;
            f2 = f3;
            f3 = f1 + f2;
        }
        return f2;
    }
 
    // Prints Fibonacci Representation of n using
    // greedy algorithm
    public static void printFibRepresntation(int n)
    {
        while (n > 0) {
            // Find the greates Fibonacci Number smaller
            // than or equal to n
            int f = nearestSmallerEqFib(n);
 
            // Print the found fibonacci number
            System.out.print(f + " ");
 
            // Reduce n
            n = n - f;
        }
    }
 
    // Driver method to test
    public static void main(String[] args)
    {
        int n = 30;
        System.out.println("Non-neighbouring Fibonacci "
                           + " Representation of " + n + " is");
 
        printFibRepresntation(n);
    }
}
 
// Code Contributed by Mohit Gupta_OMG


Python
# Python program for Zeckendorf's theorem. It finds
# representation of n as sum of non-neighbouring
# Fibonacci Numbers.
 
# Returns the greatest Fibonacci Numberr smaller than
# or equal to n.
def nearestSmallerEqFib(n):
     
    # Corner cases
    if (n == 0 or n == 1):
        return n
        
    # Finds the greatest Fibonacci Number smaller
    # than n.
    f1, f2, f3 = 0, 1, 1
    while (f3 <= n):
        f1 = f2;
        f2 = f3;
        f3 = f1 + f2;
    return f2;
 
 
# Prints Fibonacci Representation of n using
# greedy algorithm
def printFibRepresntation(n):
     
    while (n>0):
 
        # Find the greates Fibonacci Number smaller
        # than or equal to n
        f = nearestSmallerEqFib(n);
  
        # Print the found fibonacci number
        print f,
  
        # Reduce n
        n = n-f
 
# Driver code test above functions
n = 30
print "Non-neighbouring Fibonacci Representation of", n, "is"
printFibRepresntation(n)


C#
// C# program for Zeckendorf's theorem.
// It finds the representation of n as
// sum of non-neighbouring  Fibonacci
// Numbers.
using System;
 
class GFG {
    public static int nearestSmallerEqFib(int n)
    {
        // Corner cases
        if (n == 0 || n == 1)
            return n;
 
        // Find the greatest Fibonacci
        // Number smaller than n.
        int f1 = 0, f2 = 1, f3 = 1;
        while (f3 <= n) {
            f1 = f2;
            f2 = f3;
            f3 = f1 + f2;
        }
        return f2;
    }
 
    // Prints Fibonacci Representation
    // of n using greedy algorithm
    public static void printFibRepresntation(int n)
    {
        while (n > 0) {
            // Find the greates Fibonacci
            // Number smallerthan or equal
            // to n
            int f = nearestSmallerEqFib(n);
 
            // Print the found fibonacci number
            Console.Write(f + " ");
 
            // Reduce n
            n = n - f;
        }
    }
 
    // Driver method
    public static void Main()
    {
        int n = 40;
        Console.WriteLine("Non-neighbouring Fibonacci "
                          + " Representation of " + n + " is");
 
        printFibRepresntation(n);
    }
}
 
// Code Contributed by vt_m


PHP
 0)
    {
         
        // Find the greates Fibonacci
        // Number smaller than or
        // equal to n
        $f = nearestSmallerEqFib($n);
 
        // Print the found
        // fibonacci number
        echo $f, " ";
 
        // Reduce n
        $n = $n - $f;
    }
}
 
    // Driver Code
    $n = 30;
    echo "Non-neighbouring Fibonacci Representation of ",
                                            $n, " is \n";
    printFibRepresntation($n);
 
// This code is contributed by ajit
?>


Javascript


输出
Non-neighbouring Fibonacci Representation of 30 is 
21 8 1 

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

以上贪婪算法如何工作?
令小于或等于’n’的最大斐波那契数为fib(i)[第i个斐波那契数]。
然后,n – fib(i)将具有自己的表示形式,即不相邻的斐波那契数之和。
我们要确保的是没有相邻的问题。通过归纳,n-fib(i)不存在邻近问题,那么n可能存在邻近问题的唯一方法是,如果n-fib(i)在其表示中使用fib(i-1)。
因此,我们需要进一步证明的是,n-fib(i)在其表示中不使用fib(i-1)
让我们用矛盾来证明这一点。如果n-fib(i)= fib(i-1)+ fib(ix)+…,则fib(i)不能是最接近n的最小斐波那契数,因为fib(i)+ fib(i-1)本身是fib(i + 1)。
因此,如果n-fib(i)包含fib(i-1),则fib(i + 1)的fib数将更接近n,这与我们认为fib(i)是最接近n的更小的fib数的假设相矛盾。 。