--------------------------------------------------------------------------- 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];}