Open In App

Count of ways in which N can be represented as sum of Fibonacci numbers without repetition

Given a number N, the task is to find the number of ways in which the integer N can be represented as a sum of Fibonacci numbers without repetition of any Fibonacci number. 

Examples:

Input: N = 13
Output: 3
Explanation: 
The possible ways to select N as 13 are: {13} {8, 5} {8, 3, 2}. Note that it is not possible to select {5 + 5 + 3} because 5 appears twice.

Input: N = 87
Output: 5
Explanation:
The possible ways to select N as 13 are: {55 + 21 + 8 + 3}, {55 + 21 + 8 + 2 + 1}, {55 + 21 + 5 + 3 + 2 + 1}, {55 + 13 + 8 + 5 + 3 + 2 + 1}, {34 + 21 + 13 + 8 + 5 + 3 + 2 + 1}.

Naive Approach: The naive idea is to write all the possible combinations that add up to given number N. Check if any combination has repeated integers then don’t increase the counter otherwise increase the count by 1 each time. Return the count at the end.

Time Complexity: O(N)
Auxiliary Space: O(1)

Efficient Approach: The idea is to use Dynamic Programming to optimize the above approach. Below are the steps:

Imagine Fibonacci coding by following way: the i-th bit of number corresponds to the i-th Fibonacci number
For Example: 16 = 13 + 3 will be written as 100100.

Starting canonical representation:                                              1000000001
After decomposing leftmost 1-bit into two smaller 1-bits:           0110000001
After decomposing 2’nd leftmost 1-bit into two smaller 1-bits:   0101100001 
After decomposing 3’rd leftmost 1-bit into two smaller 1-bits:   0101011001
After decomposing 4’th leftmost 1-bit into two smaller 1-bits:   0101010111 

For Example: N = 87

Canonical form of N = 101010100  
Other 4 possible representations of N are 101010011, 101001111, 100111111, 011111111

Below is the illustration of the same:

Hence, the answer is dp1[cnt] + dp2[cnt], where cnt is the total number of 1-bits in the canonical representation.
 

Below is the implementation of the above approach:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
long long fib[101], dp1[101];
long long dp2[101], v[101];
 
// Function to generate the
// fibonacci number
void fibonacci()
{
    // First two number of
    // fibonacci sequence
    fib[1] = 1;
    fib[2] = 2;
 
    for (int i = 3; i <= 87; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
}
 
// Function to find maximum ways to
// represent num as the sum of
// fibonacci number
int find(int num)
{
    int cnt = 0;
 
    // Generate the Canonical form
    // of given number
    for (int i = 87; i > 0; i--) {
        if (num >= fib[i]) {
            v[cnt++] = i;
            num -= fib[i];
        }
    }
 
    // Reverse the number
    reverse(v, v + cnt);
 
    // Base condition of dp1 and dp2
    dp1[0] = 1;
    dp2[0] = (v[0] - 1) / 2;
 
    // Iterate from 1 to cnt
    for (int i = 1; i < cnt; i++) {
 
        // Calculate dp1[]
        dp1[i] = dp1[i - 1] + dp2[i - 1];
 
        // Calculate dp2[]
        dp2[i] = ((v[i] - v[i - 1]) / 2)
                     * dp2[i - 1]
                 + ((v[i] - v[i - 1] - 1) / 2)
                       * dp1[i - 1];
    }
 
    // Return final ans
    return (dp1[cnt - 1] + dp2[cnt - 1]);
}
 
// Driver Code
int main()
{
    // Function call to generate the
    // fibonacci numbers
    fibonacci();
 
    // Given Number
    int num = 13;
 
    // Function Call
    cout << find(num);
    return 0;
}




// Java program for the above approach
import java.util.*;
 
class GFG{
 
static long[] fib = new long[101];
static long[] dp1 = new long[101];
static long[] dp2 = new long[101];
static long[] v = new long[101];
 
// Function to generate the
// fibonacci number
static void fibonacci()
{
     
    // First two number of
    // fibonacci sequence
    fib[1] = 1;
    fib[2] = 2;
 
    for(int i = 3; i <= 87; i++)
    {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
}
 
// Function to find maximum ways to
// represent num as the sum of
// fibonacci number
static long find(int num)
{
    int cnt = 0;
 
    // Generate the Canonical form
    // of given number
    for(int i = 87; i > 0; i--)
    {
        if (num >= fib[i])
        {
            v[cnt++] = i;
            num -= fib[i];
        }
    }
 
    // Reverse the number
    for(int i = 0; i < cnt / 2; i++)
    {
        long t = v[i];
        v[i] = v[cnt - i - 1];
        v[cnt - i - 1] = t;
    }
     
    // Base condition of dp1 and dp2
    dp1[0] = 1;
    dp2[0] = (v[0] - 1) / 2;
 
    // Iterate from 1 to cnt
    for(int i = 1; i < cnt; i++)
    {
         
        // Calculate dp1[]
        dp1[i] = dp1[i - 1] + dp2[i - 1];
 
        // Calculate dp2[]
        dp2[i] = ((v[i] - v[i - 1]) / 2) *
                 dp2[i - 1] +
                 ((v[i] - v[i - 1] - 1) / 2) *
                 dp1[i - 1];
    }
 
    // Return final ans
    return (dp1[cnt - 1] + dp2[cnt - 1]);
}
 
// Driver code
public static void main (String[] args)
{
     
    // Function call to generate the
    // fibonacci numbers
    fibonacci();
     
    // Given number
    int num = 13;
     
    // Function call
    System.out.print(find(num));
}
}
 
// This code is contributed by offbeat




# Python3 program for the above approach
fib = [0] * 101
dp1 = [0] * 101
dp2 = [0] * 101
v = [0] * 101
 
# Function to generate the
# fibonacci number
def fibonacci():
 
    # First two number of
    # fibonacci sequence
    fib[1] = 1
    fib[2] = 2
 
    for i in range(3, 87 + 1):
        fib[i] = fib[i - 1] + fib[i - 2]
 
# Function to find maximum ways to
# represent num as the sum of
# fibonacci number
def find(num):
 
    cnt = 0
 
    # Generate the Canonical form
    # of given number
    for i in range(87, 0, -1):
        if(num >= fib[i]):
            v[cnt] = i
            cnt += 1
            num -= fib[i]
 
    # Reverse the number
    v[::-1]
 
    # Base condition of dp1 and dp2
    dp1[0] = 1
    dp2[0] = (v[0] - 1) // 2
 
    # Iterate from 1 to cnt
    for i in range(1, cnt):
 
        # Calculate dp1[]
        dp1[i] = dp1[i - 1] + dp2[i - 1]
 
        # Calculate dp2[]
        dp2[i] = (((v[i] - v[i - 1]) // 2) *
                  dp2[i - 1] +
                  ((v[i] - v[i - 1] - 1) // 2) *
                  dp1[i - 1])
 
    # Return final ans
    return dp1[cnt - 1] + dp2[cnt - 1]
 
# Driver Code
 
# Function call to generate the
# fibonacci numbers
fibonacci()
 
# Given number
num = 13
 
# Function call
print(find(num))
 
# This code is contributed by Shivam Singh




// C# program for the above approach
using System;
 
class GFG{
 
static long[] fib = new long[101];
static long[] dp1 = new long[101]; 
static long[] dp2 = new long[101];
static long[] v = new long[101]; 
   
// Function to generate the 
// fibonacci number 
static void fibonacci() 
{
     
    // First two number of 
    // fibonacci sequence 
    fib[1] = 1; 
    fib[2] = 2; 
   
    for(int i = 3; i <= 87; i++)
    
        fib[i] = fib[i - 1] + fib[i - 2]; 
    
   
// Function to find maximum ways to 
// represent num as the sum of 
// fibonacci number 
static long find(long num) 
    int cnt = 0; 
   
    // Generate the Canonical form 
    // of given number 
    for(int i = 87; i > 0; i--) 
    
        if (num >= fib[i])
        
            v[cnt++] = i; 
            num -= fib[i]; 
        
    
   
    // Reverse the number 
    for(int i = 0; i < cnt / 2; i++)
    
        long t = v[i]; 
        v[i] = v[cnt - i - 1]; 
        v[cnt - i - 1] = t; 
    }
       
    // Base condition of dp1 and dp2 
    dp1[0] = 1; 
    dp2[0] = (v[0] - 1) / 2; 
   
    // Iterate from 1 to cnt 
    for(int i = 1; i < cnt; i++)
    
           
        // Calculate dp1[] 
        dp1[i] = dp1[i - 1] + dp2[i - 1]; 
   
        // Calculate dp2[] 
        dp2[i] = ((v[i] - v[i - 1]) / 2) * 
                 dp2[i - 1] +
                 ((v[i] - v[i - 1] - 1) / 2) * 
                 dp1[i - 1]; 
    
   
    // Return final ans 
    return (dp1[cnt - 1] + dp2[cnt - 1]); 
 
// Driver code
static void Main()
{
     
    // Function call to generate the 
    // fibonacci numbers 
    fibonacci(); 
       
    // Given number 
    int num = 13; 
       
    // Function call 
    Console.Write(find(num));
}
}
 
// This code is contributed by divyeshrabadiya07




<script>
 
// Javascript program for the above approach
var fib = Array(101).fill(0);
var dp1 = Array(101).fill(0);
var dp2 = Array(101).fill(0);
var v = Array(101).fill(0);
 
// Function to generate the
// fibonacci number
function fibonacci()
{
     
    // First two number of
    // fibonacci sequence
    fib[1] = 1;
    fib[2] = 2;
 
    for(i = 3; i <= 87; i++)
    {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
}
 
// Function to find maximum ways to
// represent num as the sum of
// fibonacci number
function find(num)
{
    var cnt = 0;
     
    // Generate the Canonical form
    // of given number
    for(i = 87; i > 0; i--)
    {
        if (num >= fib[i])
        {
            v[cnt++] = i;
            num -= fib[i];
        }
    }
 
    // Reverse the number
    for(i = 0; i < cnt / 2; i++)
    {
        var t = v[i];
        v[i] = v[cnt - i - 1];
        v[cnt - i - 1] = t;
    }
 
    // Base condition of dp1 and dp2
    dp1[0] = 1;
    dp2[0] = parseInt((v[0] - 1) / 2);
 
    // Iterate from 1 to cnt
    for(i = 1; i < cnt; i++)
    {
         
        // Calculate dp1
        dp1[i] = dp1[i - 1] + dp2[i - 1];
 
        // Calculate dp2
        dp2[i] = parseInt((v[i] - v[i - 1]) /
                           2) * dp2[i - 1] +
                 parseInt((v[i] - v[i - 1] - 1) /
                           2) * dp1[i - 1];
    }
 
    // Return final ans
    return (dp1[cnt - 1] + dp2[cnt - 1]);
}
 
// Driver code
 
// Function call to generate the
// fibonacci numbers
fibonacci();
 
// Given number
var num = 13;
 
// Function call
document.write(find(num));
 
// This code is contributed by todaysgaurav
 
</script>

Output: 
3

 

Time Complexity: O(log N)
Auxiliary Space: O(log N)


Article Tags :