Knapsack with Duplicate Items
Knapsack with Duplicate Items is a medium dynamic programming problem solved with the knapsack pattern.
The best approach, optimal (1d array, capacity ascending), runs in O(n · W) time and O(W) space.
Below are 2 approaches in Java, from recursion up.
Problem
Knapsack where each item can be taken unlimited times (unbounded knapsack). Return the maximum value within capacity W.
Examples
Example 1
- Input
W = 8, val = [10, 40, 50, 70], wt = [1, 3, 4, 5]- Output
110- Why
- The weight-5 item (70) plus the weight-3 item (40) fill all 8 units.
Example 2
- Input
W = 3, val = [1, 1], wt = [2, 1]- Output
3
Constraints
1 <= n, W <= 1000.- Each item can be taken any number of times.
Animated walkthrough
A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.
Concepts first, then the problem and every approach, step by step.
Space to play or pause · ← → to jump a step · click or drag the bar to seek
Solutions
Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.
| Approach | Time | Space |
|---|---|---|
| Recursion | exponential | O(W) |
| Optimal (1D array, capacity ascending) | O(n · W) | O(W) |
1Recursion
exponentialO(W)At item i, either take it and stay at i (it can be reused) or move on to i - 1.
- f(i, w) = max(f(i - 1, w), val[i] + f(i, w - wt[i])).
class Solution {
static int knapSack(int[] val, int[] wt, int capacity) {
return f(val, wt, val.length - 1, capacity);
}
private static int f(int[] val, int[] wt, int i, int w) {
if (i < 0) return 0;
int skip = f(val, wt, i - 1, w);
return wt[i] <= w ? Math.max(skip, val[i] + f(val, wt, i, w - wt[i])) : skip;
}
}2Optimal (1D array, capacity ascending)
O(n · W)O(W)dp[w] = best value for capacity w. For each item, loop w upward: dp[w - wt] may already include this item, which is exactly what unlimited copies need.
- For each item, for w from wt to W: dp[w] = max(dp[w], val + dp[w - wt]).
class Solution {
static int knapSack(int[] val, int[] wt, int capacity) {
int[] dp = new int[capacity + 1];
for (int i = 0; i < val.length; i++)
for (int w = wt[i]; w <= capacity; w++)
dp[w] = Math.max(dp[w], val[i] + dp[w - wt[i]]);
return dp[capacity];
}
}Edge cases to test
- An item too heavy to ever fit
Hints
Hint 1
Same as 0/1 knapsack, but loop capacity upward so an item can be reused within the same pass.
FAQ
What is the best time complexity for Knapsack with Duplicate Items?
Optimal (1D array, capacity ascending) runs in O(n · W) time and O(W) extra space.
Which pattern does Knapsack with Duplicate Items use?
It is a dynamic programming problem that uses the knapsack pattern. Other problems with the same pattern: 0 - 1 Knapsack Problem, Fractional Knapsack, Coin Change.
Is there a brute force solution for Knapsack with Duplicate Items?
Yes. Recursion takes exponential time and O(W) space. At item i, either take it and stay at i (it can be reused) or move on to i - 1.
Which edge cases should I test for Knapsack with Duplicate Items?
An item too heavy to ever fit.