← Back to DSA Course | Chapter 18: Interview Preparation | Lesson 3 of 4

Top DP समस्याएँ

Top DP problems छोटे answers याद रखकर solve होने वाले classic puzzles हैं, जैसे ways count करना या best combination ढूंढना।

DP Idea

Dynamic programming का core idea है हर distinct subproblem का answer पहली बार solve होने पर store करना, ताकि उसी subproblem के लिए कोई भी बाद की request scratch से recompute होने के बजाय तुरंत return हो।

उदाहरण: DP Idea

#include <iostream>
#include <unordered_map>
using namespace std;
unordered_map<int,int> cache;
int fib(int n) {
	if (n <= 1) return n;
	if (cache.count(n)) return cache[n];
	return cache[n] = fib(n-1) + fib(n-2);
}
int main() { cout << "Stored once, reused instantly on later requests: fib(15) = " << fib(15); return 0; }
import java.util.*;
public class Main {
	static Map<Integer,Integer> cache = new HashMap<>();
	static int fib(int n) {
		if (n <= 1) return n;
		if (cache.containsKey(n)) return cache.get(n);
		int r = fib(n-1) + fib(n-2);
		cache.put(n, r);
		return r;
	}
	public static void main(String[] args) { System.out.println("Stored once, reused instantly on later requests: fib(15) = " + fib(15)); }
}
cache = {}
def fib(n):
    if n <= 1:
        return n
    if n in cache:
        return cache[n]
    cache[n] = fib(n-1) + fib(n-2)
    return cache[n]
print("Stored once, reused instantly on later requests: fib(15) =", fib(15))
#include <stdio.h>
int cache[16]={0}, computed[16]={0};
int fib(int n) {
	if (n <= 1) return n;
	if (computed[n]) return cache[n];
	computed[n] = 1;
	return cache[n] = fib(n-1) + fib(n-2);
}
int main() { printf("Stored once, reused instantly on later requests: fib(15) = %d", fib(15)); return 0; }

Fibonacci

Fibonacci overlapping subproblems का सबसे simple illustration है: naive recursion वही छोटी Fibonacci values बार-बार recompute करता है, और हर value को पहली बार store करना तुरंत उस redundancy को fix कर देता है।

उदाहरण: Fibonacci

#include <iostream>
using namespace std;
int main() {
	int dp[11]; dp[0]=0; dp[1]=1;
	for (int i = 2; i <= 10; i++) dp[i] = dp[i-1] + dp[i-2];
	cout << "fib(10) = " << dp[10] << " built bottom-up, no recomputation";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int[] dp = new int[11]; dp[0]=0; dp[1]=1;
		for (int i = 2; i <= 10; i++) dp[i] = dp[i-1] + dp[i-2];
		System.out.println("fib(10) = " + dp[10] + " built bottom-up, no recomputation");
	}
}
dp = [0]*11
dp[1] = 1
for i in range(2, 11):
    dp[i] = dp[i-1] + dp[i-2]
print("fib(10) =", dp[10], "built bottom-up, no recomputation")
#include <stdio.h>
int main() {
	int dp[11]; dp[0]=0; dp[1]=1;
	for (int i = 2; i <= 10; i++) dp[i] = dp[i-1] + dp[i-2];
	printf("fib(10) = %d built bottom-up, no recomputation", dp[10]);
	return 0;
}

Climbing Stairs

किसी staircase (एक समय में 1 या 2 steps लेते हुए) चढ़ने के distinct ways की संख्या step n पर सीधे step n-1 और step n-2 तक पहुंचने के ways की संख्या से बनती है — Fibonacci जैसी बिल्कुल वही recurrence shape, बस अलग तरीके से framed।

उदाहरण: Climbing Stairs

#include <iostream>
using namespace std;
int main() {
	int n = 5;
	int dp[6]; dp[0]=1; dp[1]=1;
	for (int i = 2; i <= n; i++) dp[i] = dp[i-1] + dp[i-2];
	cout << "Ways to climb " << n << " stairs (1 or 2 at a time): " << dp[n];
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int n = 5;
		int[] dp = new int[6]; dp[0]=1; dp[1]=1;
		for (int i = 2; i <= n; i++) dp[i] = dp[i-1] + dp[i-2];
		System.out.println("Ways to climb " + n + " stairs (1 or 2 at a time): " + dp[n]);
	}
}
n = 5
dp = [0]*(n+1)
dp[0] = dp[1] = 1
for i in range(2, n+1):
    dp[i] = dp[i-1] + dp[i-2]
print(f"Ways to climb {n} stairs (1 or 2 at a time): {dp[n]}")
#include <stdio.h>
int main() {
	int n = 5;
	int dp[6]; dp[0]=1; dp[1]=1;
	for (int i = 2; i <= n; i++) dp[i] = dp[i-1] + dp[i-2];
	printf("Ways to climb %d stairs (1 or 2 at a time): %d", n, dp[n]);
	return 0;
}

Knapsack

Knapsack-style DP problems एक capacity constraint respect करते हुए value maximize करने के लिए items का एक subset चुनती हैं, हर item के लिए decide करते हुए कि इसे include करना extra capacity इसके consume करने के खिलाफ gained value के लायक है या नहीं।

उदाहरण: Knapsack

#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 << "Best value under capacity " << capacity << ": " << 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("Best value under capacity " + capacity + ": " + 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("Best value under capacity", capacity, ":", 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("Best value under capacity %d: %d", capacity, dp[capacity]);
	return 0;
}

DP Practice

कोई भी DP code लिखने से पहले, explicitly चार सवालों का जवाब देना मदद करता है: एक state क्या represent करती है, एक बड़ी state छोटी states से कैसे बनती है, base cases क्या हैं, और final answer table में कहां से आता है।

उदाहरण: DP Practice

#include <iostream>
using namespace std;
int main() {
	cout << "4 questions: what is a state, how is it built from smaller states, base cases, iteration order";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		System.out.println("4 questions: what is a state, how is it built from smaller states, base cases, iteration order");
	}
}
print("4 questions: what is a state, how is it built from smaller states, base cases, iteration order")
#include <stdio.h>
int main() {
	printf("4 questions: what is a state, how is it built from smaller states, base cases, iteration order");
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. fib(n) के लिए plain recursion लिखना, जो exponential है, results cache करने के बजाय।
  2. Climbing stairs के लिए base cases गलत पाना, इसलिए dp[0] और dp[1] दोनों 1 नहीं हैं।
  3. यह मान लेना कि recursion वाली हर problem DP है, जब इसे overlapping subproblems चाहिए।
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.