Skip to main content

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 n items with profit[i] and weight[i], and a knapsack of capacity w.
  • 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]

⏱️ Time & Space Complexity​

ApproachTimeSpace
MemoizationO(N Γ— W)O(N Γ— W)
TabulationO(N Γ— W)O(N Γ— W)
Space OptimizedO(N Γ— W)O(W)

⚠️ Edge Cases​

  • weight[i] > w β†’ can’t take that item.
  • Repeated use of item is allowed, so take call remains on i (not i - 1).
  • profit[i] = 0 or weight[i] = 0 β†’ handled by base case (avoid infinite loop).

πŸ’‘ Other Approaches​

TypeWhen to Use
Recursive Only ❌Too slow
Memoization βœ…Easy to understand
Tabulation βœ…Clean bottom-up logic
Space Optimized βœ…Best for constrained W

  • 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.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚑
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

πŸ’‘Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→