Knapsack Problem
0-1 Knapsack Problem
Given weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. In other words, given two integer arrays val[0..n-1] and weight[0..n-1] which represent values and weights associated with n items respectively. Also given an integer W which represents knapsack capacity, find out the maximum value subset of val[] such that sum of the weights of this subset is smaller than or equal to W. You cannot break an item, either pick the complete item, or don’t pick it (0-1 property).
We can use dynamic programming to solve this problem. We create a 2 dimensional array dp[i][j]
which represents the the maximum value we can make by putting the first i
item in a knapsack with j
capacity. We have:
dp[i][0] = dp[0][j] = 0
dp[i][j] = dp[i-1][j]
ifweight[i] > j
dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + val[i])
ifj >= weight[i]
Using two dimensional array:
1 |
|
Output:
1 |
|
Using one dimensional array. In the inner loop, we loop backward because it makes sure that when we are calculating dp[j]
, we already have the result for dp[j-weight[i]]
, in other words, which is the result for dp[i-1][j-weight[i-1]]
. If we loop forward, that will be dp[i][j-weight[i-1]]
.
1 |
|
Output:
1 |
|
If we need to fill full the knapsack, then initially dp[0] = 0
, dp[1..W] = -∞
because if W=0
that means we can put an item that has weight 0 to the knapsack to fill up its weight, in other words, we don’t need to put any item into the knapsack and it’s legal, so the maximum value will be 0. Other W
doesn’t have a solution, so they are undefined, so we initialize them to INT_MIN
.
1 |
|
Output:
1 |
|
Complete Knapsack Problem
In Complete Knapsack Problem, for each item, you can put as many times as you want. Therefore, if capacity allows, you can put 0, 1, 2, … ∞ items for each type.
To solve it, we can just change the above solution’s inner loop order to forward.
1 |
|
Output:
1 |
|
Source: