Printing Items in 0/1 Knapsack in C++

Given weights and values of n items; the task is to print the items according to 0/1 knapsack for the following weights and values in a knapsack of capacity W, to get the maximum total value in the knapsack.

What is 0/1 Knapsack?

Knapsack is like a bag with only a fixed size or a bag which can handle a certain amount of weight. Each item which is included in a knapsack have some value(profit) and some weight to it. We have to add those weights which will get us the maximum profit according to the total weight a knapsack could hold.

So we have weights, their value(profit) and total weight of bag which a knapsack can hold, so in 0/1 knapsack we just mention 1 and 0 to the item which are included or not where 0 is for the item that can’t be added in a bag, whereas 1 is for the item that can be included in the knapsack.

Let’s understand with the help of a simple Example −

Let us assume val[] = {1, 2, 5, 6}//value or profit
wt[] = {2, 3, 4, 5}//weight
W = 8//Capacity

Its knapsack table would be −

knapsack.jpg

The Knapsack table can be filled with the help of the following formula −

K [i ,w] = max ⁡{K [i−1, w], K [i−1, w−wt [i]] + Val[i]}

Solving the table using backtracking approach,

Now we have the data of every item their profits and the maximum of the profit within the maximum weight we can get after adding certain items.

• Start backtracking form k[n][w], where the k[n][w] is 8.
• We will go in upward direction as the blue arrow guides to all way to the up where the black arrows are going. So the 8 is in 4th row only so we will include the 4th object, this means we got the maximum profit after adding the 4th item.
• We will minus the total profit that is 8 with the profit obtained by adding the 4th item i.e, 6 we will get 2.
• We will backtrack the table to look for when we get 2 as the maximum profit. We got it when we add the 2nd item
• So we will add 2nd and 4th item in a knapsack to fill the bag efficiently and to achieve the maximum profit.

Example

Input: val[] = {60, 100, 120}
wt[] = {10, 20, 30}
w = 50
Output: 220 //max value
30 20 //weights
Explanation: to reach till the maximum weight i.e. 50 we will add two weights value,
30 whose value is 120 and 20 whose value is 100

Input: val[] = {10, 40, 50}
wt[] = {2, 4, 5}
w = 6
Output: 50
4 2
Explanation: to reach till the maximum weight i.e. 6 we will add two weights value, 4
whose value is 40 and 2 whose value is 10.

Algorithm

Start
Step 1-> In function max(int a, int b)
Return (a > b) ? a : b
Step 2-> In function printknapSack(int W, int wt[], int val[], int n)
Decalare i, w, K[n + 1][W + 1]
Loop For i = 0 and i <= n and i++
Loop For w = 0 and w <= W and w++
If i == 0 || w == 0 then,
Set K[i][w] = 0
Else If wt[i - 1] <= w then,
Set K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w])
Else
Set K[i][w] = K[i - 1][w]
Set res = K[n][W]
Print res
Set w = W
Loop For i = n and i > 0 && res > 0 and i--
If res == K[i - 1][w] then,
Continue
Else {
Print wt[i - 1])
Set res = res - val[i - 1]
Set w = w - wt[i - 1]
Step 3-> In function int main()
Set val[] = { 50, 120, 70 }
Set wt[] = { 10, 20, 30 }
Set W = 50
Set n = sizeof(val) / sizeof(val[0])
Call function printknapSack(W, wt, val, n)
Stop

Example

Live Demo

#include <bits/stdc++.h>
int max(int a, int b) { return (a > b) ? a : b; }
// Prints the items which are put in a knapsack of capacity W
void printknapSack(int W, int wt[], int val[], int n) {
int i, w;
int K[n + 1][W + 1];
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++) {
for (w = 0; w <= W; w++) {
if (i == 0 || w == 0)
K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = max(val[i - 1] +
K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else
K[i][w] = K[i - 1][w];
}
}
// stores the result of Knapsack
int res = K[n][W];
printf("maximum value=%d\n", res);
w = W;
printf("weights included\n");
for (i = n; i > 0 && res > 0; i--) {
if (res == K[i - 1][w])
continue;
else {
printf("%d ", wt[i - 1]);
res = res - val[i - 1];
w = w - wt[i - 1];
}
}
}
// main code
int main() {
int val[] = { 50, 120, 70 };
int wt[] = { 10, 20, 30 };
int W = 50;
int n = sizeof(val) / sizeof(val[0]);
printknapSack(W, wt, val, n);
return 0;
}

Output

maximum value=190
weights included
30 20