What is the main problem with using plain recursion for some problems?
Plain recursion can lead to repeated calculations of the same subproblems, causing exponential time complexity and slow performance.
Click to reveal answer
beginner
What does Dynamic Programming (DP) do to improve recursion?
DP stores the results of subproblems so they don't need to be recalculated, turning exponential time into polynomial time.
Click to reveal answer
intermediate
What are the two main approaches to implement Dynamic Programming?
Top-down (memoization) which uses recursion with caching, and bottom-up (tabulation) which builds solutions from smaller subproblems up.
Click to reveal answer
beginner
Why does recursion alone fail for problems like Fibonacci sequence calculation?
Because it recalculates the same Fibonacci numbers many times, leading to exponential growth in calls and slow execution.
Click to reveal answer
beginner
How does memoization help recursion?
Memoization saves the results of recursive calls in a cache so that when the same inputs occur again, the stored result is used instead of recalculating.
Click to reveal answer
What is the main benefit of using Dynamic Programming over plain recursion?
AMakes code shorter but slower
BUses more memory without performance gain
CRemoves the need for recursion
DAvoids repeated calculations by storing results
✗ Incorrect
Dynamic Programming stores results of subproblems to avoid repeated calculations, improving performance.
Which problem is a classic example where recursion alone is inefficient?
APrinting numbers from 1 to n
BSorting an array
CCalculating Fibonacci numbers
DFinding maximum in a list
✗ Incorrect
Calculating Fibonacci numbers with plain recursion recalculates the same values many times, causing inefficiency.
What is memoization in Dynamic Programming?
AStoring results of subproblems to reuse
BBreaking problems into smaller parts
CUsing loops instead of recursion
DIgnoring repeated subproblems
✗ Incorrect
Memoization caches results of subproblems to avoid repeated work.
Which approach builds solutions from the smallest subproblems up?
ATop-down (memoization)
BBottom-up (tabulation)
CPlain recursion
DDivide and conquer
✗ Incorrect
Bottom-up DP solves smaller subproblems first and uses their results to solve bigger ones.
When does recursion alone typically fail?
AWhen subproblems overlap and are recalculated multiple times
BWhen problems have no subproblems
CWhen problems are very small
DWhen no results need to be stored
✗ Incorrect
Recursion fails when it recalculates overlapping subproblems repeatedly, causing inefficiency.
Explain why recursion alone can be inefficient and how Dynamic Programming solves this problem.
Think about how many times the same calculation happens in recursion.
You got /5 concepts.
Describe the difference between top-down and bottom-up Dynamic Programming approaches.
One builds from the top problem down, the other from the bottom up.
You got /5 concepts.
Practice
(1/5)
1. Why do we use dynamic programming instead of plain 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 multiple steps.
C. Because dynamic programming uses loops instead of functions.
D. Because recursion always causes errors in programs.
Solution
Step 1: Understand recursion's limitation
Recursion solves problems by calling itself but can repeat the same work many times.
Step 2: How dynamic programming helps
Dynamic programming saves results of subproblems to avoid repeating calculations, making it 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: Recursion repeats work; DP remembers results to save time [OK]
2. Which of the following Rust function signatures correctly shows a recursive function for Fibonacci numbers?
easy
A. fn fib(n: u32) -> u32 { loop { n = n + 1; } }
B. fn fib(n: u32) -> u32 { if n <= 1 { n } else { fib(n-1) + fib(n-2) } }
C. fn fib(n: u32) -> u32 { return n * n; }
D. fn fib(n: u32) -> u32 { let mut sum = 0; for i in 0..n { sum += i; } sum }
Solution
Step 1: Identify recursive call pattern
fn fib(n: u32) -> u32 { if n <= 1 { n } else { fib(n-1) + fib(n-2) } } calls fib(n-1) and fib(n-2) inside the function, which is classic recursion for Fibonacci.
Step 2: Check other options for recursion
Options A, C, and D do not call fib recursively; they use loops or simple calculations.
Final Answer:
fn fib(n: u32) -> u32 { if n <= 1 { n } else { fib(n-1) + fib(n-2) } } -> Option B
Quick Check:
Recursive calls in function = fn fib(n: u32) -> u32 { if n <= 1 { n } else { fib(n-1) + fib(n-2) } } [OK]
Hint: Look for function calling itself inside its body [OK]
Common Mistakes:
Choosing loop-based or arithmetic-only functions
Missing the recursive calls in the function body
Confusing loops with recursion
3. What is the output of this Rust code using recursion to calculate Fibonacci of 4?
fn fib(n: u32) -> u32 {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
}
fn main() {
println!("{}", fib(4));
}