📖 Scenario: You are packing items into a bag that can carry a limited weight. Each item has a weight and a value. You can take any number of each item to maximize the total value without exceeding the bag's weight limit.
🎯 Goal: Build a Rust program that calculates the maximum value you can carry in the bag using the unbounded knapsack approach.
📋 What You'll Learn
Create a vector of tuples called items where each tuple contains the weight and value of an item
Create a variable called capacity to represent the maximum weight the bag can carry
Write a function called unbounded_knapsack that takes capacity and items and returns the maximum value
Print the maximum value returned by the unbounded_knapsack function
💡 Why This Matters
🌍 Real World
This problem models packing or resource allocation where you can use unlimited quantities of items, such as cutting raw materials or filling containers.
💼 Career
Understanding dynamic programming and knapsack problems is important for software engineers working on optimization, logistics, and resource management.
Progress0 / 4 steps
1
Create the items list
Create a vector called items with these exact tuples: (2, 10), (3, 15), (5, 40). Each tuple represents (weight, value).
DSA Rust
Hint
Use vec![(2, 10), (3, 15), (5, 40)] to create the vector.
2
Set the bag capacity
Create a variable called capacity and set it to 8 to represent the maximum weight the bag can carry.
DSA Rust
Hint
Use let capacity = 8; to set the bag's weight limit.
3
Write the unbounded knapsack function
Write a function called unbounded_knapsack that takes capacity: usize and items: &Vec<(usize, usize)> and returns a usize. Use dynamic programming to find the maximum value that fits in the bag. Use a vector dp of size capacity + 1 initialized with zeros. For each weight from 1 to capacity, check all items. If the item's weight is less than or equal to the current weight, update dp[weight] with the maximum of its current value and dp[weight - item_weight] + item_value. Return dp[capacity].
DSA Rust
Hint
Use nested loops: outer for weights 1 to capacity, inner for each item. Update dp array with max values.
4
Print the maximum value
Call the unbounded_knapsack function with capacity and &items. Print the returned maximum value using println!("{}", max_value).
DSA Rust
Hint
Call the function and print the result with println!("{}", max_value);.
Practice
(1/5)
1. What is the main difference between the Unbounded Knapsack Problem and the 0/1 Knapsack Problem?
easy
A. There is no difference; both problems are the same.
B. In Unbounded Knapsack, items cannot be repeated.
C. In 0/1 Knapsack, items can be used unlimited times.
D. In Unbounded Knapsack, you can use unlimited copies of each item.
Solution
Step 1: Understand item usage rules
In 0/1 Knapsack, each item can be chosen at most once. In Unbounded Knapsack, items can be chosen multiple times.
Step 2: Compare problem definitions
Unbounded Knapsack allows unlimited copies of each item, unlike 0/1 Knapsack.
Final Answer:
In Unbounded Knapsack, you can use unlimited copies of each item. -> Option D
Quick Check:
Unbounded = unlimited copies [OK]
Hint: Unbounded means unlimited items allowed [OK]
Common Mistakes:
Confusing 0/1 and unbounded item usage
Thinking items cannot repeat in unbounded knapsack
Assuming both problems have same constraints
2. Which of the following Rust code snippets correctly initializes the DP array for the Unbounded Knapsack problem with capacity `W`?
easy
A. let mut dp = vec![std::i32::MAX; W + 1];
B. let mut dp = vec![1; W];
C. let mut dp = vec![0; W + 1];
D. let mut dp = vec![None; W + 1];
Solution
Step 1: Understand DP array purpose
DP array stores max value for capacities from 0 to W, initialized with 0 as base case.
Step 2: Check initialization correctness
let mut dp = vec![0; W + 1]; initializes dp with zeros for all capacities including 0 to W, which is correct.
3. What will be the output of the following Rust code snippet for Unbounded Knapsack?
let weights = vec![2, 3, 4];
let values = vec![15, 20, 30];
let capacity = 7;
let mut dp = vec![0; capacity + 1];
for w in 1..=capacity {
for i in 0..weights.len() {
if weights[i] <= w {
dp[w] = dp[w].max(dp[w - weights[i]] + values[i]);
}
}
}
println!("{}", dp[capacity]);
medium
A. 65
B. 50
C. 45
D. 60
Solution
Step 1: Trace DP array updates for capacity 7
Calculate max value for each capacity:
- w=1: no items fit, dp[1]=0
- w=2: use item 0 (weight 2, value 15), dp[2]=15
- w=3: item 1 fits (3,20), dp[3]=20
- w=4: item 2 fits (4,30), dp[4]=30; also dp[4-2]=dp[2]=15 + 15=30, max=30
- w=5: check items:
item0: dp[5-2]=dp[3]=20 +15=35
item1: dp[5-3]=dp[2]=15 +20=35
item2: dp[5-4]=dp[1]=0 +30=30
max=35
- w=6:
item0: dp[6-2]=dp[4]=30 +15=45
item1: dp[6-3]=dp[3]=20 +20=40
item2: dp[6-4]=dp[2]=15 +30=45
max=45
- w=7:
item0: dp[7-2]=dp[5]=35 +15=50
item1: dp[7-3]=dp[4]=30 +20=50
item2: dp[7-4]=dp[3]=20 +30=50
max=50
Step 2: Verify final dp[7]
dp[7] = 50
Final Answer:
50 -> Option B
Quick Check:
Max value at capacity 7 = 50 [OK]
Hint: Check all items for each capacity and pick max value [OK]
Common Mistakes:
Not considering multiple uses of same item
Incorrectly updating dp array
Off-by-one errors in loops
4. Identify the bug in the following Rust code snippet for Unbounded Knapsack and select the correct fix:
let weights = vec![1, 3, 4];
let values = vec![10, 40, 50];
let capacity = 6;
let mut dp = vec![0; capacity];
for w in 1..=capacity {
for i in 0..weights.len() {
if weights[i] <= w {
dp[w] = dp[w].max(dp[w - weights[i]] + values[i]);
}
}
}
println!("{}", dp[capacity]);
medium
A. Initialize dp with size capacity + 1 instead of capacity.
B. Change loop to for w in 0..capacity instead of 1..=capacity.
C. Use dp[w + weights[i]] instead of dp[w - weights[i]].
D. Replace max with min in dp update.
Solution
Step 1: Check dp vector size
dp is initialized with size capacity (6), but indices go up to capacity (6), so dp[6] access is out of bounds.
Step 2: Fix dp size to capacity + 1
Initialize dp with size capacity + 1 to safely access dp[capacity].
Final Answer:
Initialize dp with size capacity + 1 instead of capacity. -> Option A
Quick Check:
dp size = capacity + 1 to avoid index error [OK]
Hint: DP array size must be capacity + 1 for indexing [OK]
Common Mistakes:
Off-by-one error in dp array size
Accessing dp out of bounds
Incorrect loop ranges
5. Given items with weights [1, 3, 4] and values [10, 40, 50], and a knapsack capacity of 7, what is the maximum value achievable using the Unbounded Knapsack approach?