The way I think about it, in the simplest form, dynamic programming essentially boils down to a way of solving a problem with overlapping subproblems and an optimal substructure. Memoization is a technique that can achieve similarly efficient results, but is more of an "addendum" to traditional recursive formulations to avoid the cost of solving overlapping subproblems. The two are related, but not quite the same.