What if you could pack your bag perfectly without trying every single combination by hand?
Why Unbounded Knapsack Problem in DSA Typescript?
Imagine you have a backpack and many types of items to pack. Each item has a weight and a value. You want to fill your backpack to get the highest total value. But you can take as many copies of each item as you want.
Trying to pick items one by one and checking all combinations by hand is like trying to solve a huge puzzle without a picture.
Manually trying every combination of items is slow and confusing. You might miss better choices or waste time repeating the same checks. It's easy to make mistakes and hard to know if you found the best answer.
The Unbounded Knapsack Problem uses a smart way to build up the best solution step by step. It remembers the best value for smaller weights and uses that to find the best for bigger weights. This saves time and avoids repeated work.
function maxValue(weights: number[], values: number[], capacity: number): number {
// Try all combinations manually - very slow
// No reuse of previous results
return 0; // placeholder
}function unboundedKnapsack(weights: number[], values: number[], capacity: number): number {
const dp = Array(capacity + 1).fill(0);
for (let w = 1; w <= capacity; w++) {
for (let i = 0; i < weights.length; i++) {
if (weights[i] <= w) {
dp[w] = Math.max(dp[w], dp[w - weights[i]] + values[i]);
}
}
}
return dp[capacity];
}This approach lets you quickly find the best total value for any backpack size when you can use unlimited copies of items.
Imagine a candy store where you can buy unlimited candies of different types. You want to fill your bag with candies to get the most sweetness without exceeding the bag's weight limit.
Manual checking of all item combinations is slow and error-prone.
Unbounded Knapsack uses dynamic programming to build solutions from smaller problems.
This method efficiently finds the best value when unlimited copies of items are allowed.
Practice
0/1 Knapsack Problem and the Unbounded Knapsack Problem?Solution
Step 1: Understand the item usage rules
In 0/1 Knapsack, each item can be chosen at most once. In Unbounded Knapsack, items can be chosen unlimited times.Step 2: Compare the problem constraints
Unbounded Knapsack allows repeated use of the same item, unlike 0/1 Knapsack.Final Answer:
In Unbounded Knapsack, you can use unlimited copies of each item. -> Option AQuick Check:
Unlimited item usage = In Unbounded Knapsack, you can use unlimited copies of each item. [OK]
- Confusing unbounded with fractional knapsack
- Thinking items cannot repeat
- Assuming fixed item count
Solution
Step 1: Check parameter types for correctness
Weight capacityWshould be a number, weightswtand valuesvalarrays of numbers, andnthe number of items as a number.Step 2: Identify the correct signature
function unboundedKnapsack(W: number, wt: number[], val: number[], n: number): number matches all types correctly. Others have wrong types like string instead of number.Final Answer:
function unboundedKnapsack(W: number, wt: number[], val: number[], n: number): number -> Option CQuick Check:
Correct types for all parameters = function unboundedKnapsack(W: number, wt: number[], val: number[], n: number): number [OK]
- Using string instead of number for weights or capacity
- Mixing array types
- Incorrect return type
const val = [10, 40, 50];
const wt = [1, 3, 4];
const W = 6;
function unboundedKnapsack(W: number, wt: number[], val: number[], n: number): number {
const dp = Array(W + 1).fill(0);
for (let i = 1; i <= W; i++) {
for (let j = 0; j < n; j++) {
if (wt[j] <= i) {
dp[i] = Math.max(dp[i], dp[i - wt[j]] + val[j]);
}
}
}
return dp[W];
}
console.log(unboundedKnapsack(W, wt, val, val.length));Solution
Step 1: Understand the DP array construction
We build dp array from 0 to W=6. For each capacity, we check all items and update dp[i] with max value including unlimited items.Step 2: Calculate dp values step-by-step
dp[1]=max(0, dp[0]+10)=10
dp[2]=max(0, dp[1]+10)=20
dp[3]=max(dp[3], dp[0]+40)=40, also dp[3]=max(40, dp[2]+10)=40
dp[4]=max(dp[4], dp[1]+40)=50, also dp[4]=max(50, dp[0]+50)=50
dp[5]=max(dp[5], dp[2]+40)=60, also dp[5]=max(60, dp[1]+50)=60
dp[6]=max(dp[6], dp[3]+40)=80, also dp[6]=max(80, dp[2]+50)=90Final Answer:
90 -> Option AQuick Check:
Max value for W=6 = 90 [OK]
- Not considering multiple copies of items
- Incorrect dp array updates
- Mixing 0/1 and unbounded logic
function unboundedKnapsack(W: number, wt: number[], val: number[], n: number): number {
const dp = Array(W + 1).fill(0);
for (let j = 0; j < n; j++) {
for (let i = 1; i <= W; i++) {
if (wt[j] <= i) {
dp[i] = Math.max(dp[i], dp[i - wt[j]] + val[j]);
}
}
}
return dp[W];
}Solution
Step 1: Analyze loop order for unbounded knapsack
For unbounded knapsack, outer loop should iterate over capacities (i), inner loop over items (j) to allow multiple uses of items.Step 2: Identify the bug in loop order
Here, outer loop is over items and inner over capacity, which is incorrect and leads to wrong results.Final Answer:
Loops are reversed; inner loop should be over items, outer over capacity -> Option DQuick Check:
Correct loop order = capacity outer, items inner [OK]
- Swapping loop order
- Wrong dp initialization
- Incorrect return index
val = [5, 10, 15] and weights wt = [1, 3, 4], and a knapsack capacity W = 7, what is the maximum value achievable using the Unbounded Knapsack approach?Solution
Step 1: Calculate dp array values for capacities 1 to 7
dp[0]=0
dp[1]=max(0, dp[0]+5)=5
dp[2]=max(0, dp[1]+5)=10
dp[3]=max(dp[3], dp[0]+10)=10, also dp[3]=max(10, dp[2]+5)=10
dp[4]=max(dp[4], dp[1]+10)=15, also dp[4]=max(15, dp[0]+15)=15
dp[5]=max(dp[5], dp[2]+10)=20, also dp[5]=max(20, dp[1]+15)=20
dp[6]=max(dp[6], dp[3]+10)=20, also dp[6]=max(20, dp[2]+15)=25
dp[7]=max(dp[7], dp[4]+10)=25, also dp[7]=max(25, dp[3]+15)=25Step 2: Find maximum value at capacity 7
The maximum value achievable is 25, but check if better combinations exist:
Try dp[7] = dp[3] + val[2] = 10 + 15 = 25
Try dp[7] = dp[4] + val[1] = 15 + 10 = 25
Try dp[7] = dp[6] + val[0] = 25 + 5 = 30 (better)
Update dp[7] = 30
Try dp[7] = dp[3] + val[2] = 10 + 15 = 25 (less than 30)
So final dp[7] = 30Final Answer:
30 -> Option BQuick Check:
Maximum value for W=7 = 30 [OK]
- Ignoring multiple item usage
- Stopping at first max value found
- Not updating dp array correctly
Ready to prove it?
Pass the test and this pattern moves unknown
