Dynamic programming is an optimization approach that breaks down problems into overlapping sub-problems whose results are reused (memoization). It contrasts with divide and conquer by relying on previous outputs to optimize larger sub-problems, with two main approaches: top-down (recursive with memoization) and bottom-up (iterative with tabulation). Key applications include the Fibonacci series, knapsack problem, and Bellman-Ford algorithm for shortest paths.