---------------------------------------------------------------------------
COMP 731 - Data Struc & Algorithms - Lecture 26 - Tuesday, September 5, 2000
---------------------------------------------------------------------------

Today: 

Dynamic Programming, continued 
   o Thief's problem


Today I tried to lead the students to solve the following
problem together:

Thief's problem:

The thief has broken into your house, where he finds N items,
item i having value v_i (dollars) and weight w_i (kilograms)  
The thief can only carry B kilograms.
What items should he take so as to maximize the value of his load?

Formally:

Given: N; v_1, ..., v_N;  w_N, ..., w_N; B

Find: A subset T of {1..N} such that 

      sum     v_i
     i in T

      but subject to: 

      sum     w_i  <=    B
     i in T


First step:  Generalize:

   Let A[n,b] = the maximal value using only items 1 ... n 
                having weight <= b

So we are interested in A[N,B], but we will calculate all the
other values, too.

Now write a recurrence relation:
         /  0                    if n=0
A[n,b]  =|  A[n-1,b]             if n>=1, w_n>b     
         \  max { A[n-1,b-w_n]+v_n , A[n-1, b]} if n>=1 and w_n <= b

                 take the item     do not take the item


Example:

   item   1  2  3  4  5
   value  5  8  6  4  3     thief can carry 10
   weight 4  6  4  2  2


Fill in the table!

           0   1   2   3   4   5   6   7   8   9   10
         ---------------------------------------------
 0       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------
 1       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------
 2       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------
 3       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------
 4       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------
 5       |   |   |   |   |   |   |   |   |   |   |   | 
         ---------------------------------------------


Writing the program: 

  int A[N+1][B+1], w[N+1], v[N+1], n, b, B

  // get values for w,v,B;

  // compute the table

  for (b=0; b<=B; b++) A[0][b]=0;
  for (n=1; n<=N; n++)
    for (b=0; b<=B; b++) 
      if (w[n]>b)  A[n][b]=A[n-1][b];
      else A[n][b]=max(A[n-1][b],A[n-1][b-w[n]]+v[n];


  // recover the answer!

  cout << "Answer is " << A[N][B] << endl;
  b = B;
  for (n=N; n; n--) 
    if (A[n][b]==A[n-1][b]) cout << "Don't take item " << n << endl;
    else {cout << "Take item " << n << endl; b -= w[n];}