Why Dynamic Programming and When Recursion Alone Fails
📖 Scenario: Imagine you want to find the number of ways to climb a staircase with 5 steps. You can climb either 1 step or 2 steps at a time. This is a common problem where recursion alone can be slow because it repeats the same calculations many times.We will explore how recursion works here and why it can be inefficient. Then, we will see how dynamic programming helps by remembering past results to avoid repeated work.
🎯 Goal: Build a simple program in C that uses recursion to count ways to climb stairs, then add a helper array to store results (dynamic programming) to make it faster.
📋 What You'll Learn
Create a recursive function to count ways to climb stairs
Add an array to store intermediate results (memoization)
Modify the recursive function to use the stored results
Print the number of ways to climb 5 steps
💡 Why This Matters
🌍 Real World
Counting ways to climb stairs is like many problems in real life where you combine smaller steps to reach a goal, such as planning routes or breaking tasks into parts.
💼 Career
Understanding why recursion alone can be inefficient and how dynamic programming optimizes it is important for software engineers solving optimization and combinatorial problems.
Progress0 / 4 steps
1
Create a recursive function to count ways to climb stairs
Write a recursive function called countWays that takes an integer n (number of steps) and returns the number of ways to climb the stairs. Use the base cases: if n is 0 or 1, return 1. Otherwise, return the sum of countWays(n - 1) and countWays(n - 2). Also, in main, call countWays with 5 and store the result in an integer variable called result.
DSA C
Hint
Use the base cases to stop recursion. For other cases, call countWays for n-1 and n-2 and add the results.
2
Add an array to store intermediate results (memoization)
Create a global integer array called memo of size 6 (to store results for steps 0 to 5). Initialize all elements to -1 to indicate uncalculated values.
DSA C
Hint
Declare the array outside all functions so it is global. Initialize all elements to -1.
3
Modify the recursive function to use the stored results
Update the countWays function to check if memo[n] is not -1. If so, return memo[n]. Otherwise, calculate the value recursively, store it in memo[n], and then return it.
DSA C
Hint
Use the memo array to save results and avoid repeated calculations.
4
Print the number of ways to climb 5 steps
Add a printf statement in main to print the value of result with the message: "Number of ways to climb 5 steps: %d\n".
DSA C
Hint
Use printf to show the final answer clearly.
Practice
(1/5)
1. Why do we use dynamic programming instead of just recursion for some problems?
easy
A. Because recursion alone can repeat the same calculations many times, making it slow.
B. Because recursion cannot solve problems with loops.
C. Because dynamic programming uses less memory than recursion always.
D. Because recursion is only for sorting problems.
Solution
Step 1: Understand recursion's limitation
Recursion solves problems by calling itself but often recalculates the same results multiple times.
Step 2: Role of dynamic programming
Dynamic programming stores these repeated results to avoid recalculations, making the solution faster.
Final Answer:
Because recursion alone can repeat the same calculations many times, making it slow. -> Option A
Quick Check:
Recursion repeats work, DP saves results [OK]
Hint: DP saves repeated results to speed up recursion [OK]
Common Mistakes:
Thinking recursion can't handle loops
Believing DP always uses less memory
Assuming recursion is only for sorting
2. Which of the following is the correct way to declare a memoization array in C for dynamic programming?
easy
A. memo = new int[1000];
B. int memo[] = 0;
C. int memo[1000] = {0};
D. int memo(1000);
Solution
Step 1: Check C array declaration syntax
In C, arrays are declared with size and optional initialization like int memo[1000] = {0};
Step 2: Analyze options
int memo[1000] = {0}; uses correct syntax. int memo[] = 0; is invalid syntax. int memo(1000); uses parentheses which is wrong in C. memo = new int[1000]; uses 'new' which is C++ syntax.
Final Answer:
int memo[1000] = {0}; -> Option C
Quick Check:
C arrays use brackets [] [OK]
Hint: Use brackets [] to declare arrays in C [OK]
Common Mistakes:
Using C++ 'new' in C code
Using parentheses instead of brackets
Not initializing memo array properly
3. What will be the output of the following C code snippet?
int fib(int n, int memo[]) {
if (n <= 1) return n;
if (memo[n] != -1) return memo[n];
memo[n] = fib(n-1, memo) + fib(n-2, memo);
return memo[n];
}
int main() {
int memo[6];
for (int i = 0; i < 6; i++) memo[i] = -1;
printf("%d", fib(5, memo));
return 0;
}
medium
A. 5
B. 8
C. 13
D. Runtime error
Solution
Step 1: Understand the Fibonacci function with memoization
fib(5) calculates Fibonacci of 5 using memo array initialized with -1 to store results.
4. Identify the error in this recursive Fibonacci function without memoization:
int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n-1) + fib(n-3);
}
medium
A. Base cases are missing.
B. It should call fib(n-2) instead of fib(n-3).
C. Function will cause infinite recursion.
D. No error, code is correct.
Solution
Step 1: Check recursive calls in Fibonacci
Fibonacci is defined as fib(n) = fib(n-1) + fib(n-2).
Step 2: Identify incorrect call
Code calls fib(n-3) instead of fib(n-2), which is wrong and breaks Fibonacci definition.
Final Answer:
It should call fib(n-2) instead of fib(n-3). -> Option B
Quick Check:
Fibonacci uses n-1 and n-2 calls [OK]
Hint: Fibonacci sums fib(n-1) and fib(n-2) only [OK]
Common Mistakes:
Using wrong recursive calls
Missing base cases
Thinking code is correct as is
5. You want to find the minimum number of coins to make a value using coins of denominations 1, 3, and 4. Why is recursion alone inefficient here, and how does dynamic programming help?
hard
A. Recursion cannot handle multiple coin types; dynamic programming can.
B. Recursion always gives wrong answers; dynamic programming is always correct.
C. Recursion uses loops which slow it down; dynamic programming uses no loops.
D. Recursion repeats subproblems; dynamic programming stores results to avoid repeats.
Solution
Step 1: Understand recursion inefficiency
Recursion tries all combinations repeatedly, recalculating same subproblems many times.
Step 2: How dynamic programming improves
Dynamic programming saves results of subproblems (like minimum coins for smaller values) to reuse, reducing time drastically.
Final Answer:
Recursion repeats subproblems; dynamic programming stores results to avoid repeats. -> Option D
Quick Check:
DP saves repeated work, recursion repeats it [OK]
Hint: DP stores sub-results; recursion repeats work [OK]
Common Mistakes:
Thinking recursion can't handle multiple coins
Believing recursion uses loops
Assuming recursion is always wrong
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.