Bird
Raised Fist0
DSA C++programming

Tabulation Bottom Up DP in DSA C++

Choose your learning style10 modes available
Mental Model
Solve a big problem by first solving all smaller problems and storing their answers in a table. Then build up to the final answer step by step.
Analogy: Imagine climbing stairs where you know how to get to the first step, then the second, and so on, until you reach the top. You remember how you got to each step so you don't repeat work.
Index: 0  1  2  3  4  5
Value: _  _  _  _  _  _
          ↑
Table stores answers for smaller problems first.
Dry Run Walkthrough
Input: Find the 5th Fibonacci number using bottom-up tabulation
Goal: Calculate Fibonacci(5) by filling a table from the bottom up
Step 1: Initialize table with base cases: fib[0] = 0, fib[1] = 1
fib: [0, 1, _, _, _, _]
Why: Base cases are known and needed to build further values
Step 2: Calculate fib[2] = fib[1] + fib[0] = 1 + 0 = 1
fib: [0, 1, 1, _, _, _]
Why: Use previous two results to find next Fibonacci number
Step 3: Calculate fib[3] = fib[2] + fib[1] = 1 + 1 = 2
fib: [0, 1, 1, 2, _, _]
Why: Build next value using stored smaller results
Step 4: Calculate fib[4] = fib[3] + fib[2] = 2 + 1 = 3
fib: [0, 1, 1, 2, 3, _]
Why: Continue building up the table
Step 5: Calculate fib[5] = fib[4] + fib[3] = 3 + 2 = 5
fib: [0, 1, 1, 2, 3, 5]
Why: Final answer is now computed using all smaller answers
Result:
fib: [0, 1, 1, 2, 3, 5]
Answer: 5
Annotated Code
DSA C++
#include <iostream>
#include <vector>

// Function to compute nth Fibonacci number using bottom-up DP
int fibonacci(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    std::vector<int> fib(n + 1, 0);
    fib[0] = 0; // base case
    fib[1] = 1; // base case

    for (int i = 2; i <= n; ++i) {
        fib[i] = fib[i - 1] + fib[i - 2]; // build current from previous two
    }

    return fib[n];
}

int main() {
    int n = 5;
    int result = fibonacci(n);
    std::cout << "Fibonacci(" << n << ") = " << result << std::endl;
    return 0;
}
fib[0] = 0; // base case fib[1] = 1; // base case
Set known starting values for the smallest problems
for (int i = 2; i <= n; ++i) { fib[i] = fib[i - 1] + fib[i - 2]; }
Fill the table from bottom up by combining previous results
return fib[n];
Return the final answer after table is complete
OutputSuccess
Fibonacci(5) = 5
Complexity Analysis
Time: O(n) because we fill the table once from 0 to n
Space: O(n) because we store all Fibonacci numbers up to n in a table
vs Alternative: Compared to naive recursion which is exponential, tabulation is much faster and avoids repeated work
Edge Cases
n = 0
Returns 0 immediately using base case
DSA C++
if (n == 0) return 0;
n = 1
Returns 1 immediately using base case
DSA C++
if (n == 1) return 1;
When to Use This Pattern
When a problem can be broken into smaller overlapping subproblems and you want to avoid repeated work, use bottom-up tabulation to build answers from smallest to largest.
Common Mistakes
Mistake: Not initializing base cases before filling the table
Fix: Always set base cases explicitly before the loop
Mistake: Filling table in wrong order (e.g., from n down to 0)
Fix: Fill table from smallest subproblem (0) up to n to ensure dependencies are ready
Summary
Computes answers to problems by filling a table from smallest subproblems up to the final problem.
Use when a problem can be divided into smaller overlapping subproblems with known base cases.
The key is to solve and store all smaller problems first so the big problem can be solved easily.

Practice

(1/5)
1. What is the main idea behind Tabulation Bottom Up DP in dynamic programming?
easy
A. Build a table from the smallest subproblems up to the main problem
B. Solve the problem by recursion without storing results
C. Use random guesses to find the solution
D. Start solving from the largest problem and break it down

Solution

  1. Step 1: Understand bottom-up approach

    Tabulation means filling a table starting from the smallest subproblems, so we solve all smaller parts first.
  2. Step 2: Compare with other methods

    Unlike recursion without memory, bottom-up avoids repeated work by storing results in a table.
  3. Final Answer:

    Build a table from the smallest subproblems up to the main problem -> Option A
  4. Quick Check:

    Bottom-up DP = Build table from small to big [OK]
Hint: Think: solve small parts first, then bigger ones [OK]
Common Mistakes:
  • Confusing bottom-up with recursion without memoization
  • Thinking it starts from the largest problem
  • Ignoring the use of a table to store results
2. Which of the following is the correct way to declare a DP table for Fibonacci numbers using tabulation in C++?
easy
A. int dp[]; dp[1] = 1;
B. int dp[100] = {0}; dp[1] = 1;
C. int dp[100]; dp[0] = 1;
D. int dp[100] = {1}; dp[2] = 1;

Solution

  1. Step 1: Check array initialization

    int dp[100] = {0}; dp[1] = 1; initializes dp with zeros and sets dp[1] = 1, which is correct for Fibonacci base cases.
  2. Step 2: Identify errors in other options

    int dp[]; dp[1] = 1; has no size for dp array, invalid in C++. int dp[100]; dp[0] = 1; sets dp[0] = 1 which is incorrect base case. int dp[100] = {1}; dp[2] = 1; initializes dp with 1 at dp[0], which is wrong.
  3. Final Answer:

    int dp[100] = {0}; dp[1] = 1; -> Option B
  4. Quick Check:

    Correct base initialization = int dp[100] = {0}; dp[1] = 1; [OK]
Hint: Initialize dp array with zeros and set base cases explicitly [OK]
Common Mistakes:
  • Not specifying array size
  • Wrong base case initialization
  • Assuming default values without initialization
3. What will be the output of the following C++ code using bottom-up DP to find the 5th Fibonacci number?
int fib(int n) {
  int dp[6] = {0};
  dp[1] = 1;
  for (int i = 2; i <= n; i++) {
    dp[i] = dp[i-1] + dp[i-2];
  }
  return dp[n];
}

int main() {
  std::cout << fib(5);
  return 0;
}
medium
A. 5
B. 8
C. 3
D. 13

Solution

  1. Step 1: Trace dp array filling

    dp[0]=0, dp[1]=1; then dp[2]=1, dp[3]=2, dp[4]=3, dp[5]=5 by adding previous two.
  2. Step 2: Return dp[5]

    dp[5] is 5, so output is 5.
  3. Final Answer:

    5 -> Option A
  4. Quick Check:

    Fibonacci(5) = 5 [OK]
Hint: Remember Fibonacci sequence: 0,1,1,2,3,5... [OK]
Common Mistakes:
  • Off-by-one errors in indexing
  • Confusing dp[0] and dp[1] values
  • Returning wrong dp index
4. Identify the error in this bottom-up DP code for computing factorial of n:
int factorial(int n) {
  int dp[100];
  dp[0] = 1;
  for (int i = 1; i <= n; i++) {
    dp[i] = dp[i-1] * i;
  }
  return dp[n];
}
medium
A. dp array not initialized to zero
B. Loop should start from i = 0
C. dp array size might be too small for large n
D. No error, code is correct

Solution

  1. Step 1: Check dp array size

    dp array size is fixed at 100, so if n > 99, dp[i] access is out of bounds causing error.
  2. Step 2: Analyze other parts

    Initialization and loop logic are correct; loop starts at 1 and dp[0] = 1 is base case.
  3. Final Answer:

    dp array size might be too small for large n -> Option C
  4. Quick Check:

    Array size must fit n [OK]
Hint: Ensure dp array size >= n to avoid overflow [OK]
Common Mistakes:
  • Assuming dp size is always enough
  • Starting loop at wrong index
  • Ignoring base case initialization
5. Given the problem to find the minimum number of coins to make amount 11 using coins {1, 3, 5}, which bottom-up DP table entry dp[11] will hold after running this code?
int coins[] = {1, 3, 5};
int n = 11;
int dp[12];
dp[0] = 0;
for (int i = 1; i <= n; i++) {
  dp[i] = 1000; // large number
  for (int c : coins) {
    if (i - c >= 0) {
      dp[i] = std::min(dp[i], dp[i-c] + 1);
    }
  }
}
std::cout << dp[n];
hard
A. 6
B. 5
C. 4
D. 3

Solution

  1. Step 1: Understand DP logic for coin change

    dp[i] stores minimum coins for amount i. For 11, check coins 1,3,5 and pick minimum.
  2. Step 2: Calculate dp values up to 11

    dp[0]=0; dp[1]=1; dp[2]=2; dp[3]=1; dp[4]=2; dp[5]=1; dp[6]=2; dp[7]=3; dp[8]=2; dp[9]=3; dp[10]=2; dp[11]=3 (e.g., 5+5+1 or 3+3+5)
  3. Final Answer:

    3 -> Option D
  4. Quick Check:

    Minimum coins for 11 = 3 [OK]
Hint: Build dp from 0 to n, pick min coins at each step [OK]
Common Mistakes:
  • Not initializing dp[0] = 0
  • Using max int instead of large number
  • Forgetting to check i - coin >= 0
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard