0-1 Knapsack समस्या
In this page:
dp = [[0] * (W + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(W + 1):
dp[i][w] = dp[i - 1][w] # skip item
if weight[i - 1] <= w:
dp[i][w] = max(dp[i][w], value[i - 1] + dp[i - 1][w - weight[i - 1]]) # take item
Problem Idea
0-1 knapsack problem में, आप एक fixed weight capacity वाले bag में कौन से items pack करें यह चुन रहे हैं total value maximize करने के लिए, लेकिन हर item या तो पूरी तरह लिया जाता है या पूरी तरह छोड़ दिया जाता है — किसी का हिस्सा लेने या इसे दो बार लेने का कोई तरीका नहीं।
उदाहरण: Problem Idea
#include <iostream>
using namespace std;
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5;
cout << "Choose subset of items, weight <= " << capacity << ", each item fully taken or fully left";
return 0;
}
public class Main {
public static void main(String[] args) {
int[] weights = {2,3,4}, values = {3,4,5};
int capacity = 5;
System.out.println("Choose subset of items, weight <= " + capacity + ", each item fully taken or fully left");
}
}
weights, values, capacity = [2,3,4], [3,4,5], 5
print(f"Choose subset of items, weight <= {capacity}, each item fully taken or fully left")
#include <stdio.h>
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5;
printf("Choose subset of items, weight <= %d, each item fully taken or fully left", capacity);
return 0;
}
Login to try C/C++/Java code in the editor
DP State
dp[i][w] पहले i items सिर्फ उपयोग करते हुए w capacity के knapsack से achievable best total value represent करता है, इसलिए यह table item by item बनाना आखिरकार हर capacity के लिए best possible value दिखाता है जिसकी आपको ज़रूरत हो सकती है।
उदाहरण: DP State
#include <iostream>
using namespace std;
int main() {
int dp[4][6] = {0};
cout << "dp[i][w] = best value using first i items with capacity w; dp[3][5] is the final answer slot";
return 0;
}
public class Main {
public static void main(String[] args) {
int[][] dp = new int[4][6];
System.out.println("dp[i][w] = best value using first i items with capacity w; dp[3][5] is the final answer slot");
}
}
dp = [[0]*6 for _ in range(4)]
print("dp[i][w] = best value using first i items with capacity w; dp[3][5] is the final answer slot")
#include <stdio.h>
int main() {
int dp[4][6] = {0};
printf("dp[i][w] = best value using first i items with capacity w; dp[3][5] is the final answer slot");
return 0;
}
Login to try C/C++/Java code in the editor
Transition
हर item के लिए आपके पास बिल्कुल दो choices हैं: इसे skip करें और इसके बिना पहले से मिली best value रखें, या इसे लें (अगर यह fit हो) और इसकी value को बची capacity के best result में जोड़ें — DP transition बस इन दो options में से बेहतर लेता है।
उदाहरण: Transition
#include <iostream>
using namespace std;
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5, n = 3;
int dp[4][6] = {0};
for (int i = 1; i <= n; i++)
for (int w = 0; w <= capacity; w++) {
dp[i][w] = dp[i-1][w];
if (weights[i-1] <= w) dp[i][w] = max(dp[i][w], dp[i-1][w-weights[i-1]] + values[i-1]);
}
cout << "Best value with capacity " << capacity << ": " << dp[n][capacity];
return 0;
}
public class Main {
public static void main(String[] args) {
int[] weights = {2,3,4}, values = {3,4,5};
int capacity = 5, n = 3;
int[][] dp = new int[4][6];
for (int i = 1; i <= n; i++)
for (int w = 0; w <= capacity; w++) {
dp[i][w] = dp[i-1][w];
if (weights[i-1] <= w) dp[i][w] = Math.max(dp[i][w], dp[i-1][w-weights[i-1]] + values[i-1]);
}
System.out.println("Best value with capacity " + capacity + ": " + dp[n][capacity]);
}
}
weights, values, capacity, n = [2,3,4], [3,4,5], 5, 3
dp = [[0]*(capacity+1) for _ in range(n+1)]
for i in range(1, n+1):
for w in range(capacity+1):
dp[i][w] = dp[i-1][w]
if weights[i-1] <= w:
dp[i][w] = max(dp[i][w], dp[i-1][w-weights[i-1]] + values[i-1])
print(f"Best value with capacity {capacity}: {dp[n][capacity]}")
#include <stdio.h>
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5, n = 3;
int dp[4][6] = {0};
for (int i = 1; i <= n; i++)
for (int w = 0; w <= capacity; w++) {
dp[i][w] = dp[i-1][w];
if (weights[i-1] <= w && dp[i-1][w-weights[i-1]] + values[i-1] > dp[i][w])
dp[i][w] = dp[i-1][w-weights[i-1]] + values[i-1];
}
printf("Best value with capacity %d: %d", capacity, dp[n][capacity]);
return 0;
}
Login to try C/C++/Java code in the editor
Space Optimization
चूंकि dp[i][w] सिर्फ पिछली row (dp[i-1][...]) पर निर्भर करता है, आप 2D table को एक single 1D array में collapse कर सकते हैं, जब तक आप इसे high capacity से low capacity तक update करें ताकि गलती से कोई item दो बार reuse न हो।
उदाहरण: Space Optimization
#include <iostream>
using namespace std;
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5;
int dp[6] = {0};
for (int i = 0; i < 3; i++)
for (int w = capacity; w >= weights[i]; w--)
dp[w] = max(dp[w], dp[w-weights[i]] + values[i]);
cout << "1D array updated high-to-low, best value: " << dp[capacity];
return 0;
}
public class Main {
public static void main(String[] args) {
int[] weights = {2,3,4}, values = {3,4,5};
int capacity = 5;
int[] dp = new int[6];
for (int i = 0; i < 3; i++)
for (int w = capacity; w >= weights[i]; w--)
dp[w] = Math.max(dp[w], dp[w-weights[i]] + values[i]);
System.out.println("1D array updated high-to-low, best value: " + dp[capacity]);
}
}
weights, values, capacity = [2,3,4], [3,4,5], 5
dp = [0]*(capacity+1)
for i in range(3):
for w in range(capacity, weights[i]-1, -1):
dp[w] = max(dp[w], dp[w-weights[i]] + values[i])
print("1D array updated high-to-low, best value:", dp[capacity])
#include <stdio.h>
int main() {
int weights[] = {2,3,4}, values[] = {3,4,5}, capacity = 5;
int dp[6] = {0};
for (int i = 0; i < 3; i++)
for (int w = capacity; w >= weights[i]; w--)
if (dp[w-weights[i]] + values[i] > dp[w]) dp[w] = dp[w-weights[i]] + values[i];
printf("1D array updated high-to-low, best value: %d", dp[capacity]);
return 0;
}
Login to try C/C++/Java code in the editor
Practice
0-1 knapsack 'choose or don't choose' optimization problems के लिए classic example है, और यही DP shape तब भी reappear होता है जब आप एक hard constraint के तहत items का एक subset select कर रहे हों।
उदाहरण: Practice
#include <iostream>
using namespace std;
int main() {
cout << "Same DP shape reappears anywhere you select a subset of items under a hard constraint";
return 0;
}
public class Main {
public static void main(String[] args) {
System.out.println("Same DP shape reappears anywhere you select a subset of items under a hard constraint");
}
}
print("Same DP shape reappears anywhere you select a subset of items under a hard constraint")
#include <stdio.h>
int main() {
printf("Same DP shape reappears anywhere you select a subset of items under a hard constraint");
return 0;
}
Login to try C/C++/Java code in the editor
- 1D version में capacity को upward loop करना, जो उसी item को कई बार उपयोग होने देता है (वह unbounded knapsack है)।
- इसे लेने से पहले यह न जांचना कि item का weight current capacity से ज़्यादा नहीं है।
- Table को
0के अलावा किसी और चीज़ से initialize करना, याdp[i][w]कोdp[w][i]के साथ mix up करना।
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first: