Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find maximum amount we can get by taking different items within the capacity in Python
The 0/1 Knapsack problem is a classic optimization problem where we have items with weights and values, and we need to find the maximum value we can obtain within a given weight capacity. Each item can be taken at most once.
Given two lists weights and values of the same length and a capacity k, where weights[i] and values[i] represent the weight and value of the i-th item, we need to find the maximum value achievable without exceeding the capacity limit.
Problem Example
If we have weights = [2, 3, 4], values = [2, 6, 4], and capacity = 6, the output will be 8.
We can take items with weights 2 and 3 (total weight = 5 ? 6) to get values 2 + 6 = 8.
Dynamic Programming Approach
We use a 2D DP table where dp[i][j] represents the maximum value achievable using the first i items with capacity j ?
Algorithm Steps
- Create a DP matrix of size (n+1) × (capacity+1) initialized with 0
- For each item i and capacity j:
- If i = 0 or j = 0, then dp[i][j] = 0 (base case)
- If weights[i-1] ? j, we can include the item: dp[i][j] = max(value + dp[i-1][j-weight], dp[i-1][j])
- Otherwise, we skip the item: dp[i][j] = dp[i-1][j]
- Return dp[n][capacity]
Implementation
def knapsack_01(weights, values, capacity):
n = len(weights)
# Create DP table
dp = [[0 for j in range(capacity + 1)] for i in range(n + 1)]
# Fill the DP table
for i in range(n + 1):
for j in range(capacity + 1):
if i == 0 or j == 0:
dp[i][j] = 0
elif weights[i-1] <= j:
# Include current item vs exclude current item
include = dp[i-1][j - weights[i-1]] + values[i-1]
exclude = dp[i-1][j]
dp[i][j] = max(include, exclude)
else:
dp[i][j] = dp[i-1][j]
return dp[n][capacity]
# Test the function
weights = [2, 3, 4]
values = [2, 6, 4]
capacity = 6
result = knapsack_01(weights, values, capacity)
print(f"Maximum value: {result}")
Maximum value: 8
Optimized Space Solution
We can optimize space complexity to O(capacity) by using only two rows ?
def knapsack_optimized(weights, values, capacity):
n = len(weights)
# Use only one row, process from right to left
dp = [0] * (capacity + 1)
for i in range(n):
# Traverse backwards to avoid overwriting needed values
for j in range(capacity, weights[i] - 1, -1):
dp[j] = max(dp[j], dp[j - weights[i]] + values[i])
return dp[capacity]
# Test the optimized function
weights = [2, 3, 4]
values = [2, 6, 4]
capacity = 6
result = knapsack_optimized(weights, values, capacity)
print(f"Maximum value (optimized): {result}")
Maximum value (optimized): 8
Comparison
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| 2D DP | O(n × capacity) | O(n × capacity) | When you need to track which items are selected |
| 1D DP | O(n × capacity) | O(capacity) | When only maximum value is needed |
Conclusion
The 0/1 Knapsack problem can be solved efficiently using dynamic programming. The 2D approach is intuitive and allows backtracking to find selected items, while the 1D approach optimizes space usage when only the maximum value is required.
