0/1, unbounded, bounded, and multi-dimensional knapsack patterns
Pick or skip items with weight/cost constraints; iterate capacity in proper order to avoid reuse bugs.
Use for resource allocation with capacity constraints and combinatorial choices.
Each item at most once
def knapsack_01(weights, values, W):
dp=[0]*(W+1)
for w,v in zip(weights, values):
for c in range(W, w-1, -1):
dp[c]=max(dp[c], dp[c-w]+v)
return dp[W]
Unlimited items
def unbounded_knapsack(weights, values, W):
dp=[0]*(W+1)
for i,(w,v) in enumerate(zip(weights, values)):
for c in range(w, W+1):
dp[c]=max(dp[c], dp[c-w]+v)
return dp[W]
Limited counts or multi-constraints
# Bounded counts via binary splitting
def bounded_knapsack(weights, values, counts, W):
items=[]
for w,v,c in zip(weights,values,counts):
k=1
while c>0:
take=min(k,c); items.append((w*take, v*take)); c-=take; k<<=1
dp=[0]*(W+1)
for w,v in items:
for c in range(W, w-1, -1):
dp[c]=max(dp[c], dp[c-w]+v)
return dp[W]
def template(*args, **kwargs):
# General template placeholder
pass
n items by capacity W.
1D rolling array often works.