1665. Minimum Initial Energy to Finish Tasks
Learn how a greedy sorting strategy based on task 'buffer' minimizes the initial energy needed to complete all tasks in any order.
Problem Statement
You are given an array tasks where tasks[i] = [actual_i, minimum_i]:
actual_iis the actual amount of energy you spend to finish theith task.minimum_iis the minimum amount of energy you require to begin theith task.
For example, if the task is [10, 12] and your current energy is 11, you cannot start this task. However, if your current energy is 13, you can complete this task, and your energy will be 3 after finishing it.
You can finish the tasks in any order you like.
Return the minimum initial amount of energy you will need to finish all the tasks.
Examples
Example 1
Input: tasks = [[1,2],[2,4],[4,8]]
Output: 8
Explanation: Starting with 8 energy, finish tasks in this order:
- 3rd task. Energy = 8 - 4 = 4.
- 2nd task. Energy = 4 - 2 = 2.
- 1st task. Energy = 2 - 1 = 1.
Starting with 7 energy does not work because we cannot begin the 3rd task.
Example 2
Input: tasks = [[1,3],[2,4],[10,11],[10,12],[8,9]]
Output: 32
Example 3
Input: tasks = [[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
Output: 27
Constraints
1 <= tasks.length <= 10^51 <= actual_i <= minimum_i <= 10^4
Explanation
Think of actual and minimum as two separate dimensions for each task.
The difference minimum - actual is basically how much extra energy you need just to start the task — sort of the “entry cost” on top of what you actually burn. So the idea is to start with the tasks that have the smallest entry cost and leave the ones with the bigger entry cost for later.
Why? Consider two tasks A and B. If we do A then B, we need initial energy ≥ max(minimum_A, actual_A + minimum_B). If we do B then A, we need ≥ max(minimum_B, actual_B + minimum_A). Doing A before B is better when minimum_A - actual_A ≤ minimum_B - actual_B, i.e., when A has a smaller buffer.
Once you sort by that difference, the answer builds up naturally: you need at least minimum of the first task to start, and for each next task you either already have enough carry-over energy or you need to top up to that task’s minimum.
Code
class Solution {
public:
int minimumEffort(vector<vector<int>>& tasks) {
sort(tasks.begin(), tasks.end(), [&](auto &a, auto &b) {
return (a[1] - a[0]) < (b[1] - b[0]);
});
int ans = tasks[0][1], n = tasks.size();
for (int i = 1; i < n; i++) {
ans = max(ans + tasks[i][0], tasks[i][1]);
}
return ans;
}
};