🖨️ Printing Instructions: Press Ctrl/Cmd + P and select "Save as PDF".
1

Dynamic Programming: Knapsack, LCS, and Design Patterns

2

Learning Goals

3

Paradigms Revisited: DP vs Greedy vs D&C

4

Divide & Conquer

5

Greedy Algorithms

6

Dynamic Programming

7

0/1 Knapsack Problem

8

The Setup

9

Why Greedy Fails Here

10

Defining the Subproblem

11

The Recurrence

12

Interactive Demo: 0/1 Knapsack

13

Knapsack-DP Algorithm

Knapsack(v, w, n, W)
  let K[0..n][0..W] be a new table
  for i = 0 to n
    for current_w = 0 to W
      if i == 0 or current_w == 0
        K[i][current_w] = 0 // Base case
      else if w[i] <= current_w
        K[i][current_w] = max(K[i-1][current_w], 
                              v[i] + K[i-1][current_w - w[i]])
      else
        K[i][current_w] = K[i-1][current_w]
  return K[n][W]
14

Complexity Analysis

15

Optimizing Space

16

Space-Optimized Knapsack

Knapsack-1D(v, w, n, W)
  let DP[0..W] be array initialized to 0
  for i = 1 to n
    for current_w = W down to w[i]
      DP[current_w] = max(DP[current_w], 
                          v[i] + DP[current_w - w[i]])
  return DP[W]
17

Longest Common Subsequence

18

Problem Definition

19

Defining the Subproblem

20

The Recurrence

21

LCS-Length Algorithm

LCS-Length(X, Y)
  m = length(X), n = length(Y)
  let C[0..m][0..n] be a new table
  
  for i = 0 to m: C[i][0] = 0
  for j = 0 to n: C[0][j] = 0
  
  for i = 1 to m
    for j = 1 to n
      if X[i] == Y[j]
        C[i][j] = C[i-1][j-1] + 1
      else
        C[i][j] = max(C[i-1][j], C[i][j-1])
        
  return C[m][n]
22

Interactive Demo: LCS Table

23

Reconstructing the String

24

The DP Design Pattern Summarized

25

The Universal 4-Step Recipe

26

Common Pitfalls to Avoid

27

Lecture Summary

28

Supplementary Resources