Dynamic Programming is a very powerful mathematical technique, often utilised in programming, for solving optimization problems. Normally, minimizing or maximizing. ‘Greedy’ algorithms focus on making the best local choice at each decision making stage. Without a proof of correctness, such an algorithm is likely to fail. With Dynamic Programming, we can design our own algorithm which searches for all possibilities (which ensures correctness) whilst storing the results to avoid having to recomputed (leading to computational efficiency). Dynamic Programming solves problems by combining the solutions of subproblems. These subproblems are not, however, independent. Subproblems can share subsubproblems, but the solution to one subproblem doesn’t necessarily affect the solutions to other subproblems stemming from the same problem. Dynamic Programming reduces computation time by solving subproblems in a ‘bottom-up’ way. It stores the solution to a subproblem the first time it is solved, meaning that it can look up the solution when that subproblem is encountered subsequently. The key to Dynamic Programming is to find the structure of optimal solutions. The steps required are as follows: 1. Generalise the structure of an optimal solution 2. Recursively define the value of an optimal solution 3. Compute the optimal solution values either top-down (with caching), or bottom-up using a table 4. Generate the optimal solution of these computed values