Dynamic programming is an Algorithmic Technique which iteratively builds a solution using smaller, related sub-problems. Algorithms using this technique can often be conceptualised as the completion of a table.
The technique is only applicable to problems which have optimal substructure and overlapping sub-problems. If only the former is true, then the technique becomes Divide and Conquer. As such, dynamic programming may be seen as the extension of divide and conquer with memoization.
A very simple example of this technique to compute Fibonacci numbers up to can be given as:
def fib(n):
S = []
S[0] = 0
S[1] = 1
for i in range(2, n):
S[i] = S[i-1] + S[i-2]
return S