You have a problem where you need to find the minimum number of coins to make a certain amount. The coin denominations are unlimited and sorted. Which condition best suggests that a greedy approach will work correctly instead of dynamic programming?
Think about when picking the largest coin first always leads to the best solution.
Greedy works when local choices lead to a global optimum. If coin denominations are multiples, picking the largest coin first always works. Otherwise, dynamic programming is needed.
What is the output of the following JavaScript code that tries to find the minimum coins for amount 11 using greedy and DP?
const coins = [1, 5, 7]; const amount = 11; function greedyCoinChange(coins, amount) { let count = 0; let remaining = amount; for (let i = coins.length - 1; i >= 0; i--) { while (coins[i] <= remaining) { remaining -= coins[i]; count++; } } return count; } function dpCoinChange(coins, amount) { const dp = Array(amount + 1).fill(Infinity); dp[0] = 0; for (let i = 1; i <= amount; i++) { for (const coin of coins) { if (coin <= i) { dp[i] = Math.min(dp[i], dp[i - coin] + 1); } } } return dp[amount]; } console.log({ greedy: greedyCoinChange(coins, amount), dp: dpCoinChange(coins, amount) });
Trace the greedy approach: it picks largest coins first until it can't, then smaller coins.
The greedy picks coins: 7 + 1 + 1 + 1 + 1 = 5 coins total. DP finds the optimal 5 + 5 + 1 = 3 coins total. So greedy is not optimal here.
Which property is essential for a problem to be solved efficiently by dynamic programming?
Think about reusing solutions to smaller parts of the problem.
Dynamic programming works when the problem can be broken into smaller overlapping subproblems and the optimal solution can be built from optimal solutions of subproblems.
Given intervals, what is the output of the greedy algorithm that selects intervals with earliest finish time?
const intervals = [
{ start: 1, end: 4 },
{ start: 3, end: 5 },
{ start: 0, end: 6 },
{ start: 5, end: 7 },
{ start: 8, end: 9 },
{ start: 5, end: 9 }
];
function intervalScheduling(intervals) {
intervals.sort((a, b) => a.end - b.end);
const result = [];
let lastEnd = -Infinity;
for (const interval of intervals) {
if (interval.start >= lastEnd) {
result.push(interval);
lastEnd = interval.end;
}
}
return result;
}
const selected = intervalScheduling(intervals);
console.log(selected.map(i => `[${i.start},${i.end}]`).join(' -> '));Sort intervals by end time and pick non-overlapping ones.
The greedy picks intervals ending earliest without overlap: [1,4], then [5,7], then [8,9].
Why does a greedy algorithm fail to find the optimal solution in some problems where dynamic programming succeeds?
Think about how greedy picks locally best choices without looking ahead.
Greedy algorithms make the best local choice at each step but may miss better overall solutions that require considering future steps. Dynamic programming considers all subproblems and builds the global optimum.
