Greedy vs Dynamic Programming: How to Know Which to Apply
📖 Scenario: Imagine you are organizing a small event and need to select tasks to complete within a limited time. You want to choose tasks that give you the most value without exceeding your available time.
🎯 Goal: You will create a simple program to decide which tasks to pick using two approaches: a greedy method and a dynamic programming method. This will help you understand when to use each approach.
📋 What You'll Learn
Create a list of tasks with exact durations and values
Set a maximum available time as a limit
Implement a greedy selection picking tasks with the best value-to-time ratio
Implement a dynamic programming solution to find the best combination of tasks
Print the selected tasks and total value for both methods
💡 Why This Matters
🌍 Real World
Choosing tasks or projects to maximize value within limited time or resources is common in event planning, project management, and budgeting.
💼 Career
Understanding when to use greedy algorithms versus dynamic programming helps software engineers optimize solutions for efficiency and correctness in real-world problems.
Progress0 / 4 steps
1
Create the list of tasks
Create a vector of pairs called tasks where each pair contains the task duration and task value. Use these exact tasks: {2, 10}, {1, 5}, {3, 15}, {2, 7}, {1, 6}.
DSA C++
Hint
Use std::vector> and initialize it with the exact pairs given.
2
Set the maximum available time
Create an integer variable called max_time and set it to 5.
DSA C++
Hint
Just create an integer variable named max_time and assign it the value 5.
3
Implement the greedy selection
Write a function called greedySelection that takes tasks and max_time as parameters. Inside, sort tasks by value-to-duration ratio in descending order, then pick tasks while total duration does not exceed max_time. Return a vector of selected task indices.
DSA C++
Hint
Sort tasks by value/duration ratio and pick tasks until time limit is reached.
4
Print the results of both methods
In main, call greedySelection(tasks, max_time) and print the indices of selected tasks and their total value. Then implement a dynamic programming solution to find the best total value within max_time and print that value.
DSA C++
Hint
Print the indices and total value of tasks selected by greedy. Then use a 2D dp array to solve the knapsack problem and print the best total value.
Practice
(1/5)
1. Which of the following best describes when to use a greedy algorithm instead of dynamic programming?
easy
A. When the problem has no clear optimal substructure
B. When the problem has optimal substructure and no overlapping subproblems
C. When the problem requires checking all possible solutions
D. When the problem has overlapping subproblems and optimal substructure
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 B
Quick Check:
Greedy = optimal substructure + no overlap [OK]
Hint: Use greedy if no overlapping subproblems exist [OK]
Common Mistakes:
Confusing overlapping subproblems as a greedy condition
Using DP when greedy suffices
Ignoring optimal substructure requirement
2. Which of the following C++ code snippets correctly initializes a DP array for a problem with 5 states?
easy
A. int dp[5];
B. int dp(5, 0);
C. vector<int> dp(5, 0);
D. int dp = new int[5];
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 C
Quick Check:
Use vector<int> dp(size, 0) for DP arrays [OK]
Hint: Use vector with size and initial value for DP arrays [OK]
Common Mistakes:
Using incorrect syntax for array initialization
Not initializing all elements to zero
Using raw pointers without delete
3. Consider the following C++ code snippet for a problem that can be solved by either greedy or DP. What is the output?
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;
}
medium
A. 6
B. 9
C. 15
D. 10
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 A
Quick Check:
Sum of even numbers = 6 [OK]
Hint: Sum only even numbers using modulo check [OK]
Common Mistakes:
Summing all numbers instead of only even
Off-by-one error in loop
Misunderstanding modulo operator
4. The following code attempts to solve the coin change problem using a greedy approach. What is the main issue?
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;
}
medium
A. Greedy approach fails for some coin sets, not always optimal
B. The loop condition is incorrect and causes infinite loop
C. Coins array is not sorted in ascending order
D. The function does not return the 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 A
Quick Check:
Greedy coin change not always optimal [OK]
Hint: Greedy coin change fails if coins not canonical [OK]
Common Mistakes:
Assuming greedy always gives minimum coins
Ignoring coin set properties
Confusing loop correctness with algorithm correctness
5. You have a set of tasks each with a deadline and profit. You want to schedule tasks to maximize profit without missing deadlines. Which approach is best and why?
struct Task {
int deadline;
int profit;
};
hard
A. Use greedy algorithm by sorting tasks by deadline only
B. Use dynamic programming to try all subsets of tasks and pick max profit
C. Use brute force to check all permutations of tasks
D. Use greedy algorithm by sorting tasks by profit and scheduling latest available slot
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 D
Quick Check:
Greedy by profit + latest slot = max profit [OK]
Hint: Sort tasks by profit, schedule latest free slot [OK]
Common Mistakes:
Sorting only by deadline misses max profit
Trying DP or brute force unnecessarily
Scheduling tasks without checking deadlines
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.