Algorithms and OOD (CSC 207 2014F) : EBoards

CSC207.01 2014F, Class 53: Dynamic Programming


Overview

Preliminaries

Admin

Upcoming Work

Extra Credit

Academic

Peer Support

Questions

The stamps problem

You go to the post-office and you need to put together the number of stamps to pay for the weight.

Describing more formally

Example

Greedy Algorithm

The Stamps Problems, Revisited

Exercise: Take a few minutes with a partner and see if you can come up with a correct algorithm that is not necessarily efficient.

Issues with enumerative algorithms

Comparing the two strategies

Dynamic Programming

Fibonacci Numbers

Code

public static int fib(int n)
{
  // Base case
  if ((n == 0) || (n == 1))
    return n;
  // Recursive case
  else 
    return fib(n-1) + fib(n-2)
} // fib(int)

Let's trace it (Sam's attempt to sketch it again on the eboard)

                fib(5)
              /        \
        fib(4)          fib(3)
        /    \           /  \
     fib(3)  fib(2)   fib(2)
     /   \      / \
  fib(2) fib(1)
   /   \
fib(1) fib(0)

Wow! We had to do fifteen or so recursive calls. That seems like a lot. The problem: We repeat a lot of work! fib(5) calls fib(4) and fib(3). fib(4) calls fib(3) again and fib(2). Each of the fib(3)'s also calls fib(2).

Strategy: Memoize! Each time you compute something (e.g., fib(2)), remember it.

So, what did we achieve?

Is there is a way that we can do something that's a little more natural?

Five minutes with your partner: Think about these issues for another solution for Fibonacci.

Idea: Start with base cases and work your way up.

public static int fib(int n)
{
  // Set up data structure
  if (n == 0) return 0;
  int[] fib = new int[n+1];
  fib[0] = 0;
  fib[1] = 1;
  // Invariant: for j < i, fib[j] is the jth Fibonacci number
  for (int i = 2; i <= n; i++)
    {
      fib[i] = fib[i-1] + fib[i-2];
    } // for
  return fib[n];
} // fib(int)

Can we do better than this?