Understanding Overlapping Subproblems and Optimal Substructure with Fibonacci
📖 Scenario: Imagine you want to find the number of ways to climb stairs where you can take 1 or 2 steps at a time. This problem can be solved using the Fibonacci sequence, which shows overlapping subproblems and optimal substructure.
🎯 Goal: Build a program that calculates the 10th Fibonacci number using a simple recursive function and then optimize it using memoization to avoid repeated calculations.
📋 What You'll Learn
Create an integer array called memo to store intermediate Fibonacci results
Write a recursive function fib that calculates Fibonacci numbers
Use memoization to store and reuse results of subproblems
Print the 10th Fibonacci number
💡 Why This Matters
🌍 Real World
Many problems like route planning, resource allocation, and sequence analysis use overlapping subproblems and optimal substructure to find efficient solutions.
💼 Career
Understanding these concepts is key for software engineers working on optimization, algorithms, and performance-critical applications.
Progress0 / 4 steps
1
Create a recursive Fibonacci function
Write a recursive function called fib that takes an integer n and returns the nth Fibonacci number using the formula: fib(n) = fib(n-1) + fib(n-2), with base cases fib(0) = 0 and fib(1) = 1.
DSA C
Hint
Use simple if statements for base cases and recursive calls for others.
2
Add memoization array
Create a global integer array called memo of size 11 and initialize all elements to -1 to store Fibonacci results for numbers 0 to 10.
DSA C
Hint
Use a for loop to set each element of memo to -1.
3
Modify fib function to use memoization
Modify the fib function to check if memo[n] is not -1 and return it if so. Otherwise, calculate fib(n) recursively, store the result in memo[n], and return it.
DSA C
Hint
Use memo[n] to save and reuse results.
4
Print the 10th Fibonacci number
In the main function, call fib(10) and print the result using printf with the format "%d\n".
DSA C
Hint
Use printf("%d\n", fib(10)); to print the result.
Practice
(1/5)
1. Which of the following best describes the concept of overlapping subproblems in dynamic programming?
easy
A. The problem requires sorting elements before solving.
B. The problem has a unique solution without repeating any subproblems.
C. The problem can be broken down into smaller subproblems which are solved multiple times.
D. The problem can be solved only using recursion without optimization.
Solution
Step 1: Understand overlapping subproblems
Overlapping subproblems means the same smaller problems appear multiple times during the solution process.
Step 2: Match with options
The problem can be broken down into smaller subproblems which are solved multiple times. correctly states that subproblems are solved multiple times, which is the key idea behind overlapping subproblems.
Final Answer:
The problem can be broken down into smaller subproblems which are solved multiple times. -> Option C
4. The following code attempts to compute the nth Fibonacci number using memoization but has a bug:
int memo[100] = {0};
int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (memo[n] != 0) return memo[n];
memo[n] = fib(n-1) + fib(n-2);
return memo[n];
}
int main() {
printf("%d", fib(0));
return 0;
}
What is the bug in this code?
medium
A. fib(0) returns 0 but memo[0] is never set, causing repeated calls.
B. The memo array is not initialized to zero.
C. The base case for fib(1) is missing.
D. The memoization check uses wrong index.
Solution
Step 1: Analyze base cases and memo usage
fib(0) returns 0 but does not store it in memo[0]. So memo[0] remains 0, which is the default value.
Step 2: Understand effect on memoization
Because the base case results are not stored in memo[n], fib(0) (and fib(1)) will be called repeatedly in the recursion tree for larger n, instead of returning a cached value.
Final Answer:
fib(0) returns 0 but memo[0] is never set, causing repeated calls. -> Option A
Quick Check:
Base case not stored in memo causes repeated calls [OK]
Hint: Store base case results in memo to avoid repeated calls [OK]
Common Mistakes:
Assuming memo array auto-initializes for base cases
Missing base case for fib(1)
Incorrect memo check condition
5. You want to find the minimum cost to reach the top of stairs where each step has a cost. You can climb 1 or 2 steps at a time. The cost array is cost[] = {10, 15, 20}. Using dynamic programming with overlapping subproblems and optimal substructure, what is the minimum cost to reach the top (beyond last step)?