# ~/Dynamic Programming

## Brandon Rozek PhD Student @ RPI studying Automated Reasoning in AI and Linux Enthusiast.

The book first goes into talking about the complexity of the Fibonacci algorithm

``````RecFibo(n):
if n = 0
return 0
else if n = 1
return 1
else
return RecFibo(n - 1) + RecFibo(n - 2)
``````

It talks about how the complexity of this is exponential.

“A single call to `RecFibo(n)` results in one recursive call to `RecFibo(n−1)`, two recursive calls to `RecFibo(n−2)`, three recursive calls to `RecFibo(n−3)`, five recursive calls to `RecFibo(n−4)`

Now consider the memoized version of this algorithm…

``````MemFibo(n):
if n = 0
return 0
else if n = 1
return 1
else
if F[n] is undefined:
F[n] <- MemFibo(n - 1) + MemFibo(n - 2)
return F[n]
``````

This actually makes the algorithm run in linear time! Dynamic programming makes use of this fact and just intentionally fills up an array with the values of \$F\$.

``````IterFibo(n):
F <- 0
F <- 1
for i <- 2 to n
F[i] <- F[i - 1] + F[i - 2]
return F[n]
``````

Here the linear complexity becomes super apparent!

Interesting snippet

“We had a very interesting gentleman in Washington named Wilson. He was secretary of Defense, and he actually had a pathological fear and hatred of the word research. I’m not using the term lightly; I’m using it precisely. His face would suffuse, he would turn red, and he would get violent if people used the term research in his presence. You can imagine how he felt, then, about the term mathematical…. I felt I had to do something to shield Wilson and the Air Force from the fact that I was really doing mathematics inside the RAND Corporation. What title, what name, could I choose?”

Dynamic programming is essentially smarter recursion. It’s about not repeating the same work.

These algorithms are best developed in two distinct stages.

(1) Formulate the problem recursively.

(a) Specification: What problem are you trying to solve?

(b) Solution: Why is the whole problem in terms of answers t smaller instances exactly the same problem?

(2) Find solutions to your recurrence from the bottom up

(a) Identify the subproblems

(b) Choose a memoization data structure

(c) Identify dependencies

(d) Find a good evaluation order

(e) Analyze space and running time

(f) Write down the algorithm

## Greedy Algorithms

If we’re lucky we can just make decisions directly instead of solving any recursive subproblems. The problem is that greedly algorithms almost never work.