/>

Lesson 3 — Intermediate

0/1 Knapsack & Subset Sum

Knapsack DP ka sabse important pattern hai — interview mein har doosre company mein aata hai. 0/1 Knapsack mein har item ya toh lo ya chhodo. Is pattern se Subset Sum, Equal Partition, Count of Subsets sab ban jaate hain. Ek pattern seekho, 5 problems solve karo!

⏱ 35 min• Intermediate• DP Patterns

0/1 Knapsack kya hai?

WHAT

Thief ko bag mein items daalne hain. Har item ka weight aur value hai. Bag ki capacity fixed hai. Maximum value le jaao — but har item sirf ek baar le sakte ho (0/1 — ya lo ya mat lo).

WHEN

Jab "ya toh include karo ya exclude karo" wala choice ho, jab items ki limit hai, jab maximum/minimum value find karni ho subject to constraints — tab 0/1 Knapsack lagao.

WHERE

Subset Sum, Equal Partition, Count of Subsets, Target Sum — ye sab 0/1 Knapsack ke variants hain. Knapsack seekh lo, baaki sab easy ho jaayega.

DP Table Visualization

# 0/1 Knapsack: Items = [1,2,3], Weights = [1,2,3], Values = [10,20,30], Capacity = 4
#
# dp[i][w] = i items tak ke saath capacity w ka maximum value
#
# Capacity — 0 1 2 3 4
# Items ?
# 0 (none) 0 0 0 0 0
# 1 (w=1, v=10) 0 10 10 10 10
# 2 (w=2, v=20) 0 10 20 30 30
# 3 (w=3, v=30) 0 10 20 30 40
#
# Har cell mein decision: item include karo ya mat karo
# Include: val[i-1] + dp[i-1][w - wt[i-1]]
# Exclude: dp[i-1][w]
# Max lo dono mein se

0/1 Knapsack Code

def knapsack(W, wt, val, n):
 # dp[i][w] = i items tak capacity w ka max value
 dp = [[0] * (W + 1) for _ in range(n + 1)]
 
 for i in range(1, n + 1):
 for w in range(1, W + 1):
 if wt[i - 1] <= w:
 # Item include kar sakte hain — max lo include/exclude mein se
 include = val[i - 1] + dp[i - 1][w - wt[i - 1]]
 exclude = dp[i - 1][w]
 dp[i][w] = max(include, exclude)
 else:
 # Weight zyada hai — sirf exclude
 dp[i][w] = dp[i - 1][w]
 
 return dp[n][W]

# Example
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(f"Maximum value: {knapsack(W, wt, val, n)}") # 220

Subset Sum Problem

Kya array ke kuch elements ka sum target ke barabar ho sakta hai? Ye 0/1 Knapsack ka variant hai — weight = element, capacity = target:

# Subset Sum — kya sum = target possible hai?
def subsetSum(arr, target):
 n = len(arr)
 dp = [[False] * (target + 1) for _ in range(n + 1)]
 
 # 0 elements se sirf 0 sum possible hai
 for i in range(n + 1):
 dp[i][0] = True
 
 for i in range(1, n + 1):
 for s in range(1, target + 1):
 if arr[i - 1] <= s:
 # Include ya exclude
 dp[i][s] = dp[i - 1][s] or dp[i - 1][s - arr[i - 1]]
 else:
 dp[i][s] = dp[i - 1][s]
 
 return dp[n][target]

# Example
arr = [3, 34, 4, 12, 5, 2]
target = 9
print(f"Sum {target} possible: {subsetSum(arr, target)}") # True (4+5)
Subset Sum = 0/1 Knapsack: Agar tumhe sirf "possible hai ya nahi" chahiye toh Subset Sum lagao (boolean DP). Agar maximum value chahiye toh Knapsack lagao (integer DP). Dono ka template same hai — sirf value type alag hai.

Equal Partition Sum

Array ko 2 subsets mein divide karo jinka sum equal ho. Agar total sum even hai toh half sum pe subset sum check karo:

# Equal Partition — array ko 2 equal sum subsets mein todo
def equalPartition(arr):
 total = sum(arr)
 if total % 2 != 0:
 return False # Odd sum — impossible!
 return subsetSum(arr, total // 2)

# Example
arr = [1, 5, 11, 5]
print(f"Equal partition possible: {equalPartition(arr)}") # True
# [1,5,5] aur [11] — dono ka sum = 11

Count of Subsets with Given Sum

Kitne subsets hain jinka sum target ke barabar ho? 0/1 se True/False ki jagah count store karo:

# Count Subsets — kitne subsets ka sum = target
def countSubsets(arr, target):
 n = len(arr)
 dp = [[0] * (target + 1) for _ in range(n + 1)]
 
 for i in range(n + 1):
 dp[i][0] = 1 # 0 sum ka 1 subset hai — empty subset
 
 for i in range(1, n + 1):
 for s in range(1, target + 1):
 if arr[i - 1] <= s:
 dp[i][s] = dp[i - 1][s] + dp[i - 1][s - arr[i - 1]]
 else:
 dp[i][s] = dp[i - 1][s]
 
 return dp[n][target]

# Example
arr = [1, 2, 3, 3]
target = 6
print(f"Subsets with sum {target}: {countSubsets(arr, target)}") # 3

Unbounded Knapsack

Agar same item baar baar le sakte ho toh Unbounded Knapsack lagta hai. Loop order change hota hai — inner loop left-to-right:

# Unbounded Knapsack — same item baar baar le sakte ho
def unboundedKnapsack(W, wt, val, n):
 dp = [0] * (W + 1)
 
 for w in range(1, W + 1):
 for i in range(n):
 if wt[i] <= w:
 dp[w] = max(dp[w], val[i] + dp[w - wt[i]])
 
 return dp[W]

# Coin Change bhi unbounded hai — same coin baar baar le sakte ho
def coinChange(coins, amount):
 dp = [float('inf')] * (amount + 1)
 dp[0] = 0
 for i in range(1, amount + 1):
 for coin in coins:
 if coin <= i and dp[i - coin] != float('inf'):
 dp[i] = min(dp[i], dp[i - coin] + 1)
 return dp[amount] if dp[amount] != float('inf') else -1

Try it: code khud likho

Exercise

Question: Array = [2, 3, 7, 8, 10] aur target = 11. Kya subset sum possible hai? "True" ya "False" daalo.

Question: Equal Partition Sum problem mein sabse pehle kya check karte hain? Sirf ek word daalo.

Common mistakes

Lesson complete?

Knapsack family samajh aa gayi? Ab LIS, LCS aur Edit Distance dekhte hain — strings pe DP ka sabse powerful application.

Popular courses: Data Science Course in Lucknow · AI Course in Lucknow · Python Course in Lucknow · Power BI Course · Data Analytics Course