Practice
def knapsack_space_optimized(weights, values, W):
n = len(weights)
dp = [0] * (W + 1)
for i in range(n):
for w in range(W, weights[i] - 1, -1):
dp[w] = max(dp[w], dp[w - weights[i]] + values[i])
return dp[W]
weights = [10, 20, 30]
values = [60, 100, 120]
W = 50
print(knapsack_space_optimized(weights, values, W))Solution
Step 1: Trace dp array updates for each item
For item 0 (weight=10, value=60), dp[w] updated for w=50 down to 10, dp[10..50]=60. For item 1 (weight=20, value=100), dp[30]=max(dp[30], dp[10]+100)=160, dp[50]=max(dp[50], dp[30]+100)=220. For item 2 (weight=30, value=120), dp[50]=max(dp[50], dp[20]+120)=max(220, 160+120)=280 but dp[20] is 60, so dp[50]=max(220, 180)=220.Step 2: Final dp[50] value
The maximum value achievable with capacity 50 is 220.Final Answer:
Option D -> Option DQuick Check:
Manual dp tracing confirms max value 220 [OK]
- Forwards iteration over w causes overcounting items.
n. What is the value of dp[4] after the outer loop iteration i = 4 completes?Solution
Step 1: Trace dp[4] updates
For i=4, j iterates over 1 and 2 because 1*1=1 <=4 and 2*2=4 <=4. - For j=1: dp[4] = min(inf, 1 + dp[3]) = 1 + dp[3] - For j=2: dp[4] = min(previous, 1 + dp[0]) = min(previous, 1 + 0) = 1 Since dp[0] = 0, dp[4] becomes 1.Step 2: Confirm dp[4] final value
dp[4] = 1 means 4 can be represented as one perfect square (2*2). This matches the expected minimal count.Final Answer:
Option B -> Option BQuick Check:
dp[4] = 1 for 4 = 2^2 [OK]
- Off-by-one errors in loop
- Ignoring dp[0] base case
Solution
Step 1: Identify loops in the algorithm
The algorithm has an outer loop over n items and an inner loop over capacities from W down to the item's weight, which can be up to W iterations.Step 2: Calculate total operations
Multiplying the loops gives O(n * W) time complexity. Recursive brute force is exponential, and linear or logarithmic complexities are incorrect here.Final Answer:
Option C -> Option CQuick Check:
Nested loops over n and W -> O(n * W) [OK]
- Confusing recursion stack space with time complexity.
Solution
Step 1: Identify DP update method
The code updates dp in-place during iteration over sums, causing double counting when num=0 or overlapping states.Step 2: Understand impact on zero values
Zero does not change sum, so updating dp in-place doubles counts incorrectly. Using a separate next_dp array avoids this.Final Answer:
Option A -> Option AQuick Check:
In-place updates cause state reuse within iteration, breaking correctness [OK]
- Not using a separate dp array for next iteration
n, but now each perfect square can only be used at most once. Which of the following changes correctly adapts the algorithm?Solution
Step 1: Understand the constraint change
Limiting each perfect square to be used at most once converts the problem from unbounded to 0/1 knapsack variant, requiring tracking which squares are used.Step 2: Identify correct DP adaptation
A 2D DP array dp[i][j] that tracks minimum squares to sum to i using first j squares correctly models the usage constraint. Other options either do not prevent reuse or do not track usage properly.Step 3: Confirm why other options fail
Keep the same bottom-up DP but iterate squares in increasing order and update dp[i] from dp[i - square] without reuse still allows reuse implicitly. Use a top-down memoized recursion with a visited set to avoid reusing squares is inefficient and complex. Change the inner loop to iterate over squares in decreasing order and update dp[i] accordingly's order change alone doesn't enforce usage limits.Final Answer:
Option C -> Option CQuick Check:
0/1 knapsack requires 2D DP to track usage [OK]
- Trying to reuse unbounded DP
- Ignoring usage constraints in DP state
