Dynamic programming is an algorithm design paradigm that can be applied to problems exhibiting optimal substructure and overlapping subproblems. It works by breaking down a problem into subproblems and storing the results of already solved subproblems, rather than recomputing them multiple times. This allows for an efficient bottom-up approach. Examples where dynamic programming can be applied include the matrix chain multiplication problem, the 0-1 knapsack problem, and finding the longest common subsequence between two strings.