knapsack
def knapsack(values, weights, capacity):
"""
0/1 Knapsack Problem using Dynamic Programming
Time Complexity: O(nW)
Space Complexity: O(nW)
where n is number of items and W is capacity
"""
n = len(values)
# Create DP table
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
# Fill DP table
for i in range(1, n + 1):
for w in range(1, capacity + 1):
if weights[i-1] <= w:
dp[i][w] = max(
values[i-1] + dp[i-1][w-weights[i-1]], # Include item
dp[i-1][w] # Exclude item
)
else:
dp[i][w] = dp[i-1][w] # Cannot include item
# Reconstruct solution
selected_items = []
w = capacity
for i in range(n, 0, -1):
if dp[i][w] != dp[i-1][w]:
selected_items.append(i-1)
w -= weights[i-1]
return dp[n][capacity], selected_items
def knapsack_optimized(values, weights, capacity):
"""
Space-optimized version of 0/1 Knapsack
Time Complexity: O(nW)
Space Complexity: O(W)
"""
n = len(values)
dp = [0] * (capacity + 1)
for i in range(n):
for w in range(capacity, weights[i]-1, -1):
dp[w] = max(dp[w], values[i] + dp[w-weights[i]])
return dp[capacity]
# Example usage
if __name__ == "__main__":
# Test case
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
# Get maximum value and selected items
max_value, selected = knapsack(values, weights, capacity)
print(f"Maximum value: {max_value}")
print(f"Selected items: {selected}")
# Get maximum value using optimized version
max_value_opt = knapsack_optimized(values, weights, capacity)
print(f"Maximum value (optimized): {max_value_opt}")
Explanation
The 0/1 Knapsack problem is to select items with maximum value while not exceeding a given weight capacity. Each item can be either taken (1) or not taken (0).
How it works:
- Create DP table with dimensions (n+1) x (W+1)
- Fill table in bottom-up manner:
- For each item
- For each possible weight
- Choose maximum of including or excluding current item
- Reconstruct solution by backtracking through table
Time Complexity:
- Best Case: O(nW)
- Average Case: O(nW)
- Worst Case: O(nW)
Space Complexity:
- Original: O(nW)
- Optimized: O(W)
Applications:
- Resource allocation
- Portfolio optimization
- Cutting stock problem
- Resource scheduling
- Budget allocation
Advantages:
- Guaranteed optimal solution
- Works for integer weights
- Can handle large values
- Easy to implement
- Can be space optimized
Disadvantages:
- Pseudo-polynomial time
- Not suitable for large W
- Requires integer weights
- May be memory intensive
- Limited to 0/1 decisions