This document discusses three algorithm design paradigms: dynamic programming, greedy algorithms, and divide-and-conquer. It provides guidelines for when each paradigm can be successfully applied to solve a problem, focusing on the properties of optimal substructure and overlapping subproblems for dynamic programming, and the greedy-choice property for greedy algorithms.