Can quick guesses fool you when the best answer hides in the details?
Greedy vs DP How to Know Which to Apply in DSA C++ - Why the Distinction Matters
Imagine you have a big jar of mixed coins and you want to pick coins to reach a certain amount of money. You try picking the biggest coins first, hoping to reach the amount quickly.
Picking the biggest coins first (greedy) sometimes fails because it misses better combinations. You waste time trying many wrong picks or get stuck without the right total.
Dynamic Programming (DP) helps by remembering past choices and combining them smartly. It checks all possibilities step-by-step to find the best solution without repeating work.
int amount = 11; int coins[] = {5, 3, 1}; int count = 0; for (int i = 0; i < 3; i++) { while (amount >= coins[i]) { amount -= coins[i]; count++; } }
#include <climits> int amount = 11; int coins[] = {5, 3, 1}; int dp[12] = {0}; for (int i = 1; i <= amount; i++) { dp[i] = INT_MAX; for (int c : coins) { if (i - c >= 0 && dp[i - c] != INT_MAX) { dp[i] = std::min(dp[i], dp[i - c] + 1); } } }
It enables finding the best solution by exploring all options smartly, not just quick guesses.
Choosing the best route on a map: greedy picks the closest next city, but DP finds the shortest total path by checking all routes.
Greedy is fast but can miss the best answer.
DP remembers past results to find the best overall solution.
Use DP when choices depend on previous decisions.
Practice
Solution
Step 1: Understand greedy algorithm conditions
Greedy algorithms work well when the problem has an optimal substructure and no overlapping subproblems, meaning making the best local choice leads to a global optimum.Step 2: Compare with dynamic programming conditions
Dynamic programming is used when there are overlapping subproblems and optimal substructure, requiring storing intermediate results to avoid recomputation.Final Answer:
When the problem has optimal substructure and no overlapping subproblems -> Option BQuick Check:
Greedy = optimal substructure + no overlap [OK]
- Confusing overlapping subproblems as a greedy condition
- Using DP when greedy suffices
- Ignoring optimal substructure requirement
Solution
Step 1: Check syntax for array initialization
int dp[5]; leaves elements uninitialized. int dp(5, 0); is invalid syntax for array initialization. int dp = new int[5]; uses incorrect syntax and memory management in C++.Step 2: Identify correct vector initialization
vector<int> dp(5, 0); correctly creates a vector of size 5 with all elements initialized to 0, which is the preferred way to initialize DP arrays in modern C++.Final Answer:
vector<int> dp(5, 0); -> Option CQuick Check:
Use vector<int> dp(size, 0) for DP arrays [OK]
- Using incorrect syntax for array initialization
- Not initializing all elements to zero
- Using raw pointers without delete
int main() {
int arr[] = {1, 2, 3, 4, 5};
int n = 5;
int sum = 0;
for (int i = 0; i < n; i++) {
if (arr[i] % 2 == 0) {
sum += arr[i];
}
}
std::cout << sum << std::endl;
return 0;
}Solution
Step 1: Identify even numbers in the array
The array is {1, 2, 3, 4, 5}. Even numbers are 2 and 4.Step 2: Calculate sum of even numbers
Sum = 2 + 4 = 6.Final Answer:
6 -> Option AQuick Check:
Sum of even numbers = 6 [OK]
- Summing all numbers instead of only even
- Off-by-one error in loop
- Misunderstanding modulo operator
int coinChange(int amount) {
int coins[] = {25, 10, 5, 1};
int count = 0;
for (int i = 0; i < 4; i++) {
while (amount >= coins[i]) {
amount -= coins[i];
count++;
}
}
return count;
}Solution
Step 1: Understand greedy approach for coin change
The greedy approach picks the largest coin repeatedly. It works only if coin denominations are canonical (like US coins).Step 2: Identify problem with greedy for arbitrary coins
For some coin sets, greedy does not give minimum coins. Dynamic programming is needed for guaranteed optimality.Final Answer:
Greedy approach fails for some coin sets, not always optimal -> Option AQuick Check:
Greedy coin change not always optimal [OK]
- Assuming greedy always gives minimum coins
- Ignoring coin set properties
- Confusing loop correctness with algorithm correctness
struct Task {
int deadline;
int profit;
};Solution
Step 1: Understand task scheduling problem
This is a classic greedy problem where tasks are sorted by profit descending, then scheduled in the latest free slot before deadline.Step 2: Compare approaches
Dynamic programming or brute force is too slow. Sorting by deadline only does not maximize profit. Greedy by profit with latest slot is efficient and optimal.Final Answer:
Use greedy algorithm by sorting tasks by profit and scheduling latest available slot -> Option DQuick Check:
Greedy by profit + latest slot = max profit [OK]
- Sorting only by deadline misses max profit
- Trying DP or brute force unnecessarily
- Scheduling tasks without checking deadlines
Ready to prove it?
Pass the test and this pattern moves unknown
