Chapter 54
HomeGiven N items, each with weight wᵢ and value vᵢ, and a knapsack of capacity W, choose a subset to maximise total value. Each item is take or leave (0/1) — no fractions. This is the classic DP problem, the gateway to 2D tabulation.
For each item i and each capacity c, you have two choices:
Exclude item i
Best value with items 1..i−1 at capacity c: dp[i-1][c]
Include item i (if it fits)
Value of item i + best with items 1..i−1 at capacity c−wᵢ: vᵢ + dp[i-1][c-wᵢ]
int knapsack(vector& weights, vector & values, int W) { int n = weights.size(); vector > dp(n + 1, vector (W + 1, 0)); for (int i = 1; i <= n; i++) { for (int c = 0; c <= W; c++) { // Exclude item i dp[i][c] = dp[i - 1][c]; // Include item i (if it fits) if (c >= weights[i - 1]) dp[i][c] = max(dp[i][c], values[i - 1] + dp[i - 1][c - weights[i - 1]]); } } return dp[n][W]; }
fn knapsack(weights: &[usize], values: &[i32], w: usize) -> i32 {
let n = weights.len();
let mut dp = vec![vec![0; w + 1]; n + 1];
for i in 1..=n {
for c in 0..=w {
dp[i][c] = dp[i - 1][c]; // exclude
if c >= weights[i - 1] {
dp[i][c] = dp[i][c].max(
values[i - 1] + dp[i - 1][c - weights[i - 1]]);
}
}
}
dp[n][w]
}
dp[i][c] = max value using first i items, capacity c.
dp[i][c] = max(dp[i-1][c], vᵢ + dp[i-1][c - wᵢ]).