Seyed Masoud Hosseini · Overview · Study log · Weekly summaries · Ideas · Search · Transcript · RSS feed
Design & Analysis of Algorithms · Lecture 12 of 34 · 52:02
Recitation 5: Dynamic Programming
Study guide
What this lecture covers
This recitation is a problem-solving session rather than a formal lecture. It opens by restating the core idea of dynamic programming, splitting a problem into subproblems and reusing solved results, then works through a sequence of examples of increasing difficulty: counting grid paths, making change with coins, and stacking rectangular blocks by height. Partway through, the class votes to spend the second half reviewing universal and perfect hashing from the previous lecture, since several students found it difficult.
After watching, you should be able to set up a dynamic programming recurrence for a new problem by asking two questions: how many distinct subproblems exist, and how much work is needed to combine each subproblem's results, and you should be able to walk through the collision-probability argument for a universal hash family and the two-level construction used for perfect hashing.
Key ideas
- DP runtime analysis pattern: for any DP solution, multiply the number of unique subproblems by the work needed to merge each subproblem's results.
- Grid-path warm-up: the number of distinct paths to a grid cell is the sum of the counts from the cell to its left and the cell below, giving
O(mn)subproblems each solved in constant time. - Coin change (make change): minimizing coins for value
nlooks polynomial innand the number of coin types, but because the input size isO(log n)bits, this runtime is actually exponential in the input size, which is why it does not contradict NP-completeness of the related knapsack problem. - Rectangular block stacking: define a subproblem as the best height achievable using only blocks compatible with (smaller in both length and width than) the current base block; sorting blocks first, then deciding whether the largest remaining block is the base or is skipped, cuts the subproblem count to
O(n). - Universal hash family (recap): a family of hash functions from which one is drawn uniformly at random so that any two distinct keys collide with probability at most
1/m; needed because any single deterministic hash function has a worst-case input, by a pigeonhole argument, when the universe of keys is much larger than the table. - Concrete universal family:
h(k) = ((a*k + b) mod p) mod m, withpprime and larger than the universe; the recitation redoes the collision-probability bound using modular inverses to show it is at most1/m. - Perfect hashing via table squaring: choosing a table size of
n^2for a universal hash function makes the probability of zero collisions amongnkeys exceed one half (a union bound over all pairs), giving a Las Vegas algorithm that succeeds with high probability afterO(log n)retries. - Two-level perfect hashing: to bring space down from
O(n^2)toO(n), hash keys once intonbins, then build a second-level perfect hash table of size proportional to the square of each bin's occupancy; Markov's inequality bounds the total second-level space.
Walkthrough
Grid paths as a first DP example (1:01)
A robot moves from grid coordinate (1,1) to (m,n), taking only up or right steps. The number of distinct paths to any cell is the sum of the paths to the cell on its left and the cell below. This gives O(mn) subproblems, each combined in constant time, for an overall O(mn) runtime, illustrating the general DP pattern of counting subproblems and per-step merge cost.
Make change and a digression on P vs NP (5:17)
Given coin denominations including a 1-cent coin (to guarantee solvability) and a target value n, the goal is the minimum number of coins to make change. The naive recursive solution tries each coin, recursing on the remainder, giving at most n distinct subproblems and O(m) work per subproblem (where m is the number of coin types), for O(nm) total. The recitation pauses to note this resembles knapsack, an NP-complete problem, and resolves the apparent contradiction: the input n only takes O(log n) bits to represent, so a runtime of O(n) is actually exponential in the input size, not polynomial.
Stacking rectangular blocks (14:41)
Given blocks with length, width and height (no rotation allowed), the task is to stack blocks so each one is strictly smaller in both length and width than the block below it, maximizing total height. A naive subproblem definition, based on an arbitrary compatible set of remaining blocks, could blow up combinatorially. The fix, echoing the earlier weighted interval scheduling recitation, is to sort blocks by length (then width) and define the subproblem as a suffix of the sorted list: either the largest remaining block is used as the current base, or it is skipped entirely. This bounds the subproblems to O(n) and, with an O(n log n) sort and a claimed but unverified O(n log n) method for finding compatible sets, gives an O(n log n) overall algorithm (naive compatible-set lookups would cost O(n^2)).
Revisiting universal hashing (33:45)
The class votes to review hashing. The setup: n keys drawn from a universe of size u, hashed into m bins. A deterministic hash function always has a worst-case input set that collides entirely, by a pigeonhole argument, when u is larger than m^2. Since the hash function itself must stay deterministic once chosen (so lookups are consistent), the fix is to pick a hash function uniformly at random from a universal family, so an attacker who does not know the chosen function cannot construct a guaranteed-bad input. A universal family guarantees any two distinct keys collide with probability at most 1/m.
A concrete universal family and perfect hashing (39:57)
The recitation re-derives the collision bound for h(k) = ((a*k + b) mod p) mod m, with p prime and larger than the universe, showing algebraically that the number of "bad" choices of a that cause a given pair of keys to collide is at most 1/m of all valid choices. It then builds toward perfect hashing: first a simple method using table size n^2, which succeeds with probability greater than one half per attempt (via a union bound over all key pairs), giving a Las Vegas algorithm with failure probability that shrinks exponentially in the number of retries, but at the cost of quadratic space. The two-level fix hashes keys into n bins with a first-level universal function, then builds a second-level perfect hash table sized at the square of each bin's key count; Markov's inequality shows the total space stays O(n) with probability greater than one half, so retrying the first-level hash function a logarithmic number of times achieves both linear space and zero collisions.
Before you watch
- Watch or review the lecture on divide and conquer or greedy algorithms that introduced weighted interval scheduling, since the block-stacking solution reuses its "sort, then include-or-exclude the extreme element" idea.
- Review the prior lecture on universal and perfect hashing, since the second half of this session assumes familiarity with hash tables, load factors, and the definitions being re-explained.
- Be comfortable with basic probability tools: union bound, indicator variables, and Markov's inequality.
Check your understanding
- For the grid-path and make-change problems, identify the number of subproblems and the per-subproblem merge cost, and explain how they combine into the overall runtime.
- Why does the naive make-change algorithm not imply P = NP, even though it looks like a polynomial-time solution to a knapsack-like problem?
- Why does defining block-stacking subproblems as arbitrary compatible sets fail to bound the subproblem count, and how does sorting fix this?
- Explain why no deterministic hash function can avoid a worst-case input when the key universe is much larger than the hash table.
- Why does squaring the table size make a universal hash function likely to have zero collisions, and why is a second level of hashing needed to keep the space linear?
Vocabulary
- recitation (noun)
- A smaller class session used to review and practice lecture material.
This recitation practices dynamic programming with several examples. - grid path (noun)
- A route moving through a grid of cells, usually only right or down.
Counting every possible grid path is a classic beginner DP problem. - make change (noun)
- The problem of finding the fewest coins that add up to a target amount.
Make change asks for the minimum number of coins for a given value. - denomination (noun)
- One of the fixed values a currency's coins or bills can have.
Each coin denomination is tried in the recursive solution. - block stacking (noun)
- The problem of arranging blocks on top of each other under size rules to maximize height.
Block stacking requires each block to be smaller than the one below it. - pigeonhole argument (noun)
- A reasoning method showing that if there are more items than slots, some slot must hold multiple items.
A pigeonhole argument proves any fixed hash function has a bad input. - worst-case input (noun)
- The specific input that makes an algorithm perform as poorly as possible.
An attacker could construct a worst-case input for a known hash function. - exponential (adjective)
- Growing extremely fast as input size increases, much faster than any fixed power.
The naive algorithm's cost is exponential in the number of input bits. - universal hash family (noun)
- A group of hash functions chosen so any two keys rarely collide, no matter which function is picked.
A universal hash family avoids a single predictable worst case. - collision (hashing) (noun)
- When two different keys are sent to the same slot by a hash function.
A collision happens when two keys hash to the same bin. - modular inverse (noun)
- A number that, multiplied by another under a modulus, gives one.
The proof uses modular inverses to bound the collision chance. - union bound (noun)
- A method estimating the chance of any of several events by adding up their individual chances.
A union bound over all pairs bounds the collision probability. - Markov's inequality (noun)
- A rule that bounds the probability a random value is much larger than its average.
Markov's inequality bounds the total second-level hashing space. - occupancy (noun)
- The number of items currently held inside a bin or slot.
The second-level table size depends on each bin's occupancy. - digression (noun)
- A brief departure from the main topic to discuss something related.
The recitation takes a digression to compare make-change with knapsack. - suffix (of a list) (noun)
- The remaining end portion of a sequence after some starting part is removed.
Each subproblem is defined as a suffix of the sorted block list. - combinatorially (adverb)
- In a way that grows extremely quickly by combining many small choices.
An arbitrary subset definition could blow up combinatorially. - solvability (noun)
- The property of a problem having at least one valid solution.
The 1-cent coin guarantees solvability of the change-making problem. - recurring (adjective)
- Happening again and again, repeatedly.
The recitation reuses a recurring sort-then-decide pattern. - resolve (a contradiction) (verb)
- To explain away an apparent conflict between two facts.
The recitation resolves the seeming contradiction with knapsack. - load factor (noun)
- The ratio of stored items to available slots in a hash table.
The load factor affects how likely collisions become. - indicator variable (noun)
- A variable that is 1 if an event happens and 0 otherwise.
Indicator variables help compute the expected number of collisions. - attacker (noun)
- Someone trying to make a system fail on purpose.
A random hash function protects against a scheming attacker. - second-level (adjective)
- Belonging to an additional layer built on top of a first one.
A second-level hash table handles collisions within each bin. - quadratic space (phrase)
- Memory use that grows with the square of the input size.
The simple perfect-hashing method costs quadratic space.
Chapters
- 0:00 MIT OpenCourseWare
- 0:20 Dynamic Programming
- 5:05 Make Change
- 14:20 Rectangular Blocks
- 45:05 Perfect Hashing
- 49:00 TwoLevel Hashing
From the YouTube description
MIT 6.046J Design and Analysis of Algorithms, Spring 2015
View the complete course: http://ocw.mit.edu/6-046JS15
Instructor: Ling Ren
In this recitation, problems related to dynamic programming are discussed.
License: Creative Commons BY-NC-SA
More information at http://ocw.mit.edu/terms
More courses at http://ocw.mit.edu
← Lecture 8: Randomization: Universal & Perfect Hashing · Lecture 9: Augmentation: Range Trees →
