01
0/1 knapsack (DP — Knapsack Sub-pattern)
Each item is taken at most once. dp[c] = max(dp[c], dp[c − w] + v) with c from high to low.
Signals in the problem statement
- ›
"each item can be used once"
- ›
"capacity W", "weight and value"
- ›
"is there a subset with sum S"
- ›
two limits at once (zeros ≤ m and ones ≤ n)
What makes it different
The backwards capacity loop is what keeps each item single-use. With two limits the table becomes 2D and both loops go backwards.
Questions
ordered from “learn the idea” to “recognise it without help”- 10/1 KnapsackWalkthroughMediumBasic Anchor·GeeksforGeeks
- 2Subset Sum ProblemWalkthroughMediumBasic Reinforcement·GeeksforGeeks
- 3Ones and ZeroesWalkthroughMediumPattern Transfer·LeetCode #474
Template
zero-one-template.cpp
// 0/1 knapsack in one row: dp[c] = best value with capacity c.
// c goes HIGH -> LOW so dp[c - w] still belongs to the previous items (each item once).
int knapsack01(int W, const vector<int>& wt, const vector<int>& val) {
vector<int> dp(W + 1, 0);
for (size_t i = 0; i < wt.size(); i++)
for (int c = W; c >= wt[i]; c--)
dp[c] = max(dp[c], dp[c - wt[i]] + val[i]); // skip vs take
return dp[W];
}Remember this · DP — Knapsack
Trigger
Pick a subset to hit a target sum / capacity, partition into two groups, count the ways to reach an amount.
Think
Is this "choose some items so their total is X"?
Key question
Can each item be used once (loop capacity backwards) or many times (loop forwards)?