Unbounded Knapsack
Problem Statement:β
You are givenΒ βnβΒ items with certainΒ βprofitβΒ andΒ βweightβΒ and a knapsack with weight capacityΒ βwβ.
You need to fill the knapsack with the items in such a way that you get the maximum profit. You are allowed to take one item multiple times.
-
Example:
Input:
'n' = 3, 'w' = 10,
'profit' = [5, 11, 13]
'weight' = [2, 4, 6]
Output: 27
Explanation:
We can fill the knapsack as:
1 item of weight 6 and 1 item of weight 4.
1 item of weight 6 and 2 items of weight 2.
2 items of weight 4 and 1 item of weight 2.
5 items of weight 2.
The maximum profit will be from case 3 = 11 + 11 + 5 = 27. Therefore maximum profit = 27.
Detailed explanation ( Input/output format, Notes, Images )
Sample Input 1:
3 15
7 2 4
5 10 20
Expected Answer:
21
Output on console:
21
Explanation of Sample Input 1
The given knapsack capacity is 15. We can fill the knapsack as [1, 1, 1] giving us profit 21 and as [1,2] giving us profit 9. Thus maximum profit will be 21.
Sample Input 2
2 3
6 12
4 17
Expected Answer:
0
Output on console:
0
Explanation of Sample Input 2:
We can clearly see that no item has weight less than knapsack capacity. Therefore we can not fill knapsack with any item.
Expected Time Complexity:
Try to solve this in O(n*w).
Constraints
1 <= n <= 10^3
1 <= w <= 10^3
1 <= profit[i] , weight[i] <= 10^8
Time Limit: 1 sec
β Solution 1: Memoizationβ
int solve(int ind, int w, vector<int> &profit, vector<int> &weight, vector<vector<int>>& dp){
// Base case: only one item to consider
if(ind == 0){
if(weight[0] <= w)
return (w / weight[0]) * profit[0]; // take as many as possible
else
return 0;
}
if(dp[ind][w] != -1) return dp[ind][w];
int notTake = solve(ind - 1, w, profit, weight, dp); // don't take current
int take = 0;
if(weight[ind] <= w){
take = profit[ind] + solve(ind, w - weight[ind], profit, weight, dp); // take again
}
return dp[ind][w] = max(take, notTake);
}
int unboundedKnapsack(int n, int w, vector<int> &profit, vector<int> &weight){
vector<vector<int>> dp(n, vector<int>(w + 1, -1));
return solve(n - 1, w, profit, weight, dp);
}
β Solution 2: Tabulationβ
int unboundedKnapsack(int n, int w, vector<int> &profit, vector<int> &weight){
vector<vector<int>> dp(n, vector<int>(w + 1, 0));
// Fill base case: only 0th item allowed
for(int i = 0; i <= w; i++){
if(weight[0] <= i){
dp[0][i] = (i / weight[0]) * profit[0];
}
}
for(int ind = 1; ind < n; ind++){
for(int tar = 0; tar <= w; tar++){
int notTake = dp[ind - 1][tar];
int take = 0;
if(weight[ind] <= tar){
take = profit[ind] + dp[ind][tar - weight[ind]];
}
dp[ind][tar] = max(take, notTake);
}
}
return dp[n - 1][w];
}
β Solution 3: Space Optimizedβ
int unboundedKnapsack(int n, int w, vector<int> &profit, vector<int> &weight){
vector<int> prev(w + 1, 0);
// Fill base case
for(int i = 0; i <= w; i++){
if(weight[0] <= i){
prev[i] = (i / weight[0]) * profit[0];
}
}
for(int ind = 1; ind < n; ind++){
vector<int> curr(w + 1, 0);
for(int tar = 0; tar <= w; tar++){
int notTake = prev[tar];
int take = 0;
if(weight[ind] <= tar){
take = profit[ind] + curr[tar - weight[ind]];
}
curr[tar] = max(take, notTake);
}
prev = curr;
}
return prev[w];
}
π Revision Notes β Unbounded Knapsackβ
β How It Worksβ
- You are given
nitems withprofit[i]andweight[i], and a knapsack of capacityw. - Unlike 0/1 Knapsack, you can take any item unlimited times.
- At each step:
- You either don't take the item.
- Or take it again, and reduce remaining capacity (
w - weight[i]).
π§© Key Formula / Recurrenceβ
dp[i][w] = max(
dp[i-1][w], // not take
profit[i] + dp[i][w - weight[i]] // take again (unbounded)
)
- Base Case:
- For
i == 0:dp[0][w] = (w / weight[0]) * profit[0]
- For
β±οΈ Time & Space Complexityβ
| Approach | Time | Space |
|---|---|---|
| Memoization | O(N Γ W) | O(N Γ W) |
| Tabulation | O(N Γ W) | O(N Γ W) |
| Space Optimized | O(N Γ W) | O(W) |
β οΈ Edge Casesβ
weight[i] > wβ canβt take that item.- Repeated use of item is allowed, so
takecall remains oni(noti - 1). profit[i] = 0orweight[i] = 0β handled by base case (avoid infinite loop).
π‘ Other Approachesβ
| Type | When to Use |
|---|---|
| Recursive Only β | Too slow |
| Memoization β | Easy to understand |
| Tabulation β | Clean bottom-up logic |
| Space Optimized β | Best for constrained W |
π Related Problemsβ
- Leetcode 518 β Coin Change II
- Unbounded Knapsack (GFG classic)
- Rod Cutting Problem
- Minimum Coins to Make Amount
π Level Up Your Engineering Mindset
Never Study in Isolation. Join Binary Dose.
Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.
Official Hub
Discord Community
Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.