Dynamic Programming — Memoization & Tabulation

Contest জিততে যে technique আপনাকে লাগবে

~60 min Advanced 30 practice problems Live code

1. What Makes a Problem DP?

  • Overlapping subproblems — একই subproblem বারবার আসে।
  • Optimal substructure — optimal solution subproblem-এর optimal-দের combine।
Divide & conquer subproblem disjoint। DP subproblem share করে — তাই caching দরকার। এটাই দুটোর মূল পার্থক্য।

2. Fibonacci — Three Ways

fib_three.c
#include <stdio.h>

// Naive: O(2^n)
long fib(int n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); }

// Memoized (top-down): O(n)
long memo[100];
long fibm(int n) {
    if (n < 2) return n;
    if (memo[n]) return memo[n];
    return memo[n] = fibm(n - 1) + fibm(n - 2);
}

// Tabulated (bottom-up): O(n), O(1) extra
long fibt(int n) {
    if (n < 2) return n;
    long a = 0, b = 1;
    for (int i = 2; i <= n; i++) { long t = a + b; a = b; b = t; }
    return b;
}

int main(void) {
    int n = 30;
    printf("fib(%d)  = %ld\n", n, fib(n));
    printf("fibm(%d) = %ld\n", n, fibm(n));
    printf("fibt(%d) = %ld\n", n, fibt(n));
    return 0;
}

3. The DP Recipe

  1. State — কোন parameter দিয়ে subproblem identify হয়?
  2. Transition — state একে অন্যের সাথে কীভাবে সম্পর্কিত?
  3. Base case — সবচেয়ে ছোট state-এ উত্তর কী?
  4. Order — dependency অনুযায়ী compute order।
  5. Answer — কোন state-এ চূড়ান্ত উত্তর?

4. 0/1 Knapsack — The Canonical DP

knapsack.c
#include <stdio.h>

// dp[i][w] = max value using first i items with capacity w
int knap(int *wt, int *val, int n, int W) {
    int dp[100][100] = {0};
    for (int i = 1; i <= n; i++)
        for (int w = 0; w <= W; w++) {
            dp[i][w] = dp[i - 1][w];
            if (wt[i - 1] <= w) {
                int take = dp[i - 1][w - wt[i - 1]] + val[i - 1];
                if (take > dp[i][w]) dp[i][w] = take;
            }
        }
    return dp[n][W];
}

int main(void) {
    int wt[]  = {1, 3, 4, 5};
    int val[] = {1, 4, 5, 7};
    printf("max value = %d\n", knap(wt, val, 4, 7));
    return 0;
}

5. LCS & Edit Distance

lcs_edit.c
#include <stdio.h>
#include <string.h>

int max(int a, int b) { return a > b ? a : b; }
int min3(int a, int b, int c) { int m = a < b ? a : b; return m < c ? m : c; }

int lcs(const char *s, const char *t) {
    int n = strlen(s), m = strlen(t);
    int dp[50][50] = {0};
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dp[i][j] = s[i-1] == t[j-1]
                     ? dp[i-1][j-1] + 1
                     : max(dp[i-1][j], dp[i][j-1]);
    return dp[n][m];
}

int edit(const char *s, const char *t) {
    int n = strlen(s), m = strlen(t);
    int dp[50][50];
    for (int i = 0; i <= n; i++) dp[i][0] = i;
    for (int j = 0; j <= m; j++) dp[0][j] = j;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dp[i][j] = s[i-1] == t[j-1]
                     ? dp[i-1][j-1]
                     : 1 + min3(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]);
    return dp[n][m];
}

int main(void) {
    printf("LCS(\"ABCBDAB\", \"BDCAB\") = %d\n", lcs("ABCBDAB", "BDCAB"));
    printf("edit(\"kitten\", \"sitting\") = %d\n", edit("kitten", "sitting"));
    return 0;
}

6. Practice Problems

  1. Fibonacci — all three ways.
    তিন ধরনের Fibonacci।
    ✨ Show Answer

    Section 2 reference।

  2. Climbing stairs (1 or 2 steps).
    Staircase — 1 বা 2 ধাপ।
    ✨ Show Answer

    ways(n) = ways(n-1) + ways(n-2) — Fibonacci-এর মতোই।

  3. Climbing stairs (1, 2, or 3).
    1/2/3 ধাপ।
    ✨ Show Answer

    ways(n) = ways(n-1) + ways(n-2) + ways(n-3), ways(0) = 1।

  4. Min cost climbing stairs.
    Min-cost staircase।
    ✨ Show Answer

    dp[i] = cost[i] + min(dp[i-1], dp[i-2])।

  5. House robber.
    House robber।
    ✨ Show Answer

    dp[i] = max(dp[i-1], dp[i-2] + a[i])।

  6. House robber II (circular).
    Circular house robber।
    ✨ Show Answer

    দুটি সমস্যা: 0..n-2 এবং 1..n-1 — প্রতিটিকে linear robber চালিয়ে max নিন।

  7. Coin change — min coins.
    Min coin change।
    ✨ Show Answer

    dp[x] = 1 + min(dp[x - c]) সব coin c-এর জন্য। dp[0] = 0।

  8. Coin change — count ways.
    Coin change — count।
    ✨ Show Answer

    Outer loop coin, inner loop x: dp[x] += dp[x - coin]। (Combinations, permutations-এ loop order উল্টে যায়।)

  9. 0/1 Knapsack.
    0/1 Knapsack।
    ✨ Show Answer

    Section 4 reference।

  10. Unbounded knapsack.
    Unbounded knapsack।
    ✨ Show Answer

    1D dp, outer i loop-এ same item বারবার নেওয়া যায়: dp[w] = max(dp[w], dp[w - wt[i]] + val[i])।

  11. Rod cutting.
    Rod cutting।
    ✨ Show Answer

    Length-n rod: dp[n] = max over i: price[i] + dp[n - i]।

  12. LCS.
    LCS।
    ✨ Show Answer

    Section 5 reference।

  13. Edit distance.
    Edit distance।
    ✨ Show Answer

    Section 5 reference।

  14. LIS — O(n²).
    LIS — O(n²)।
    ✨ Show Answer

    dp[i] = 1 + max(dp[j]) for j < i, a[j] < a[i]। Answer = max(dp)।

  15. LIS — O(n log n) via patience sorting.
    LIS — O(n log n)।
    ✨ Show Answer

    tails[] array maintain করুন; প্রতিটি element-এর জন্য binary-search করে lower_bound position-এ overwrite। Array length = LIS।

  16. Longest palindromic subsequence.
    Longest palindromic subseq।
    ✨ Show Answer

    LCS(s, reverse(s))-ই উত্তর। অথবা interval DP।

  17. Longest palindromic substring.
    Longest palindrome substring।
    ✨ Show Answer

    Center expand: প্রতিটি index থেকে ও i/i+1 জোড়া থেকে বাইরে প্রসারিত করুন। O(n²), O(1) space।

  18. Matrix chain multiplication.
    Matrix chain mult।
    ✨ Show Answer

    Interval DP: dp[i][j] = min(dp[i][k] + dp[k+1][j] + p[i-1]·p[k]·p[j]) সব k∈[i,j) এর জন্য। O(n³)।

  19. Boolean parenthesization.
    Boolean parenthesization।
    ✨ Show Answer

    3D-ish DP: (i, j, isTrue) — interval split করে operator অনুযায়ী count যোগ।

  20. Subset sum.
    Subset sum।
    ✨ Show Answer

    dp[i][s] = dp[i-1][s] || dp[i-1][s - a[i-1]]। O(nS)।

  21. Partition equal subset sum.
    Equal partition।
    ✨ Show Answer

    Total sum odd হলে impossible। নতুবা subset sum = total / 2 বের হয় কি না দেখুন।

  22. Count ways to reach (n, m) in a grid.
    Grid-এ reach (n, m)।
    ✨ Show Answer

    dp[i][j] = dp[i-1][j] + dp[i][j-1]; dp[0][0] = 1।

  23. Min path sum in a grid.
    Grid min path sum।
    ✨ Show Answer

    dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])।

  24. Max sum subarray (Kadane's).
    Kadane's।
    ✨ Show Answer

    cur = max(a[i], cur + a[i]); best = max(best, cur); — O(n)।

  25. Max product subarray.
    Max product subarray।
    ✨ Show Answer

    Negative numbers-এর জন্য min ও max দুটোই track করুন — প্রতিটি step-এ swap-এর সম্ভাবনা।

  26. Buy and sell stock I, II, III, IV.
    Stock I–IV।
    ✨ Show Answer

    I: এক transaction — best = max(best, price - min_so_far)। II: unlimited — sum of positive diffs। III/IV: k transactions — 2D DP: dp[k][i] = max(dp[k][i-1], max over j: dp[k-1][j-1] + price[i] - price[j])।

  27. Word break.
    Word break।
    ✨ Show Answer

    dp[i] = true যদি কোনো j থাকে যেখানে dp[j] true এবং s[j..i-1] dictionary-তে।

  28. Interleaving strings.
    Interleaving strings।
    ✨ Show Answer

    dp[i][j] = s3[i+j-1] == s1[i-1] && dp[i-1][j], বা == s2[j-1] && dp[i][j-1]।

  29. Bitmask DP: TSP for n ≤ 20.
    TSP — bitmask DP।
    ✨ Show Answer

    dp[mask][i] = mask visited, শেষ ছিল i-এ হলে min cost। Transition: nbhr j ∉ mask, dp[mask | (1<<j)][j] = min(..., dp[mask][i] + cost[i][j])। O(2ⁿ · n²)।

  30. Digit DP — count numbers with some property up to n.
    Digit DP।
    ✨ Show Answer

    State: (pos, tight, extra info)। Recursively প্রতিটি digit-এ try করুন; tight হলে সর্বোচ্চ d ≤ upper_bound[pos]।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
Dynamic Programming (DP)Solve big problems by combining cached subproblem answers.Subproblem-এর cached সমাধান একত্র করে বড় সমস্যা সমাধান।
MemoizationTop-down recursion + cache.Top-down recursion-এর সাথে cache।
TabulationBottom-up table filling.Bottom-up টেবিল ভরা।
StateThe set of variables identifying a subproblem.একটি subproblem চেনাতে যা যা variable লাগে।
TransitionHow one state's answer comes from smaller states.ছোট state থেকে কীভাবে এই state-এর উত্তর আসে।
Base CaseThe smallest state with a direct answer.সরাসরি উত্তর-জানা ক্ষুদ্রতম state।
Overlapping SubproblemsSame subproblem solved many times — DP candidate.একই subproblem বারবার আসে — DP-র লক্ষণ।
Optimal SubstructureOptimal answer uses optimal answers of subproblems.ভালো উত্তর ছোট subproblem-এর ভালো উত্তর থেকেই আসে।
DP TableArray storing computed answers indexed by state.State অনুযায়ী উত্তর রাখা array।
0/1 KnapsackPick subset of items to maximize value within weight limit.Weight সীমার ভিতরে value-সর্বোচ্চ subset।
LISLongest Increasing Subsequence — classic DP.সবচেয়ে দীর্ঘ ক্রমবর্ধমান subsequence।
LCSLongest Common Subsequence between two strings.দুই string-এর longest common subsequence।
Bitmask DPEncode subsets in an integer's bits as the state.Subset-কে integer-এর bit-এ encode করা DP।
Digit DPDP over digits of a number, often with a "tight" flag.সংখ্যার অঙ্ক ধরে ধরে DP।

Summary — Module 33

DP = subproblem cache। State, transition, base case — ঠিকভাবে সাজাতে পারলে DP-ই হয় যান্ত্রিক। Pattern recognition সব।

Next Module → Greedy & Number Theory।