Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum number of Fibonacci numbers to add up to n in Python?
Suppose we have a number n; we have to find the minimum number of Fibonacci numbers required to add up to n. This problem uses a greedy approach where we always pick the largest possible Fibonacci number.
So, if the input is like n = 20, then the output will be 3, as we can use the Fibonacci numbers [2, 5, 13] to sum to 20.
Algorithm
To solve this, we will follow these steps −
Initialize result counter to 0
Generate Fibonacci numbers up to n
Use greedy approach: always pick the largest Fibonacci number ? remaining sum
Subtract the chosen number and increment counter
Repeat until sum becomes 0
Example
Let us see the implementation to get better understanding −
class Solution:
def solve(self, n):
res = 0
fibo = [1, 1]
# Generate Fibonacci numbers up to n
while fibo[-1] <= n:
fibo.append(fibo[-1] + fibo[-2])
# Greedy approach: pick largest Fibonacci number
while n:
while fibo[-1] > n:
fibo.pop()
n -= fibo[-1]
res += 1
return res
# Test the solution
ob = Solution()
n = 20
print(f"Minimum Fibonacci numbers needed for {n}: {ob.solve(n)}")
The output of the above code is −
Minimum Fibonacci numbers needed for 20: 3
Step-by-Step Trace
Let's trace through the example with n = 20 −
def solve_with_trace(n):
res = 0
fibo = [1, 1]
original_n = n
# Generate Fibonacci numbers
while fibo[-1] <= n:
fibo.append(fibo[-1] + fibo[-2])
print(f"Generated Fibonacci numbers: {fibo}")
print(f"Finding minimum numbers for n = {n}")
chosen = []
while n:
while fibo[-1] > n:
fibo.pop()
chosen.append(fibo[-1])
print(f"Chose {fibo[-1]}, remaining: {n - fibo[-1]}")
n -= fibo[-1]
res += 1
print(f"Fibonacci numbers used: {chosen}")
return res
result = solve_with_trace(20)
print(f"Total count: {result}")
Generated Fibonacci numbers: [1, 1, 2, 3, 5, 8, 13, 21] Finding minimum numbers for n = 20 Chose 13, remaining: 7 Chose 5, remaining: 2 Chose 2, remaining: 0 Fibonacci numbers used: [13, 5, 2] Total count: 3
Alternative Approaches
Here's a cleaner version that doesn't modify the Fibonacci list −
def min_fibonacci_numbers(n):
# Generate Fibonacci numbers up to n
fibo = [1, 1]
while fibo[-1] < n:
fibo.append(fibo[-1] + fibo[-2])
count = 0
i = len(fibo) - 1
while n > 0:
if fibo[i] <= n:
n -= fibo[i]
count += 1
else:
i -= 1
return count
# Test with different values
test_cases = [20, 15, 1, 2, 100]
for num in test_cases:
result = min_fibonacci_numbers(num)
print(f"n = {num}: {result} Fibonacci numbers needed")
n = 20: 3 Fibonacci numbers needed n = 15: 2 Fibonacci numbers needed n = 1: 1 Fibonacci numbers needed n = 2: 1 Fibonacci numbers needed n = 100: 3 Fibonacci numbers needed
Conclusion
The greedy approach works optimally for this problem because of Zeckendorf's theorem, which states that every positive integer can be represented uniquely as a sum of non-consecutive Fibonacci numbers. The algorithm has O(log n) time complexity since Fibonacci numbers grow exponentially.
