Advantage of a typical recursive algorithm is that you divide the domain into independent sub-problems. Some recursive problems, however, do not divide into independent subproblems. This is what dynamic programming is for.
You have to have:
The motivation:
The idea is that the if the same functions get called repeatedly with the same inputs, save these results and return them instead of re-computing. This is trading space for speed. This is known as memoization.
When you call a function, check the inputs and see if they have been seen before. If they have, just retrieve the result from memory rather than recomputing it. On exit, save the inputs and save the results. Often, this can be done with only minor code changes.
This technique is called memoization, which is useful for "top down" dynamic programming.
Recursive implementation of the Fibonacci numbers:
int fib(int n) {
if (n < 1) return 0;
if (n == 1) return 1;
return fib(n - 1) + fib(n - 2);
}
This is bad. This has an exponential runtime.
If you know the basis (0 and 1), then you can use previously computed values like so:
int fib(int n) {
int f[MAX_N];
f[0] = 0;
f[1] = 1;
for (int k = 2; k <= i; k++) {
f[k] = f[k - 1] + f[k - 2];
}
return f[i];
}
This way is a lot better. This has a linear runtime.
Bottom-up dynamic programming can be used whenever top-down dynamic programming is used. Time or space requirements may become prohibitively large.
In a bottom up approach, you compute values from the base case up to the solution. This is "loosely non-adaptive", which means that it will compute all smaller cases, even if they're not needed.
In a top-down approach, you save values as they are needed. This method is generally preferred, because it is consistent with a recursive implementation, and is completely adaptive.
If the number of possible sub-problems is too high, then you're better off not trying to remember any values at all. This is an advanced technique for difficult problems. This is especially helpful when the solution domains are all dependent upon one another.