Minimum Cost to Hire K Workers
Master this topic with zero to advance depth.
Minimum Cost to Hire K Workers
There are n workers. You are given two integer arrays quality and wage where quality[i] is the quality of the ith worker and wage[i] is the minimum wage expectation for the ith worker.
We want to hire exactly k workers to form a paid group. To hire a group of k workers, we must pay them according to the following rules:
- Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
- Every worker in the paid group must be paid at least their minimum wage expectation.
Return the least amount of money needed to form a paid group satisfying the above conditions.
Visual Representation
quality = [10, 20, 5], wage = [70, 50, 30], k = 2
Ratios (wage/quality):
Worker 0: 70/10 = 7.0
Worker 1: 50/20 = 2.5
Worker 2: 30/5 = 6.0
Sorted by ratio:
[W1(2.5, q:20), W2(6.0, q:5), W0(7.0, q:10)]
To hire W2 and W1, base ratio is 6.0.
Cost = 6.0 * (20 + 5) = 150.0
To hire W0 and W2, base ratio is 7.0.
Cost = 7.0 * (10 + 5) = 105.0
Min cost = 105.0Examples
Level I: Sort by Ratio and Brute Force K-Smallest
Intuition
The total pay for K workers is determined by the highest wage / quality ratio among the chosen K workers. If we sort workers by this ratio, when we consider the i-th worker in the sorted list as having the maximum ratio, any K-1 workers before i can be hired at this ratio. To minimize cost, we should simply pick the K-1 workers with the smallest qualities from 0 to i-1.
Thought Process
- Pair each worker's quality with their
wage/qualityratio. - Sort all workers by their ratio in ascending order.
- Iterate
ifromk - 1ton - 1(a valid window to pickkworkers). - For each
i, the ratio isworker[i].ratio. - We need to pick
kqualities from index0toi(includingworker[i].quality) that are the smallest. Sinceworker[i]must be included, we pickworker[i].quality+k-1smallest qualities from0toi-1. - For a brute force approach, extract all qualities from
0toi, sort them, sum the firstk, and multiply by the ratio. - Keep track of the minimum cost.
Detailed Dry Run
quality = [10,20,5], wage = [70,50,30], k = 2 Ratios sorted: [(2.5,20), (6.0,5), (7.0,10)]
- i=1 (ratio=6.0, q=5). We need 2 qualities from idx 0 to 1. Qualities: [20, 5]. Sorted: [5, 20]. Sum = 25. Cost = 6.0 * 25 = 150.0. Min = 150.0
- i=2 (ratio=7.0, q=10). We need 2 qualities from idx 0 to 2. Qualities: [20, 5, 10]. Sorted: [5, 10, 20]. Sum = 5 + 10 = 15. Cost = 7.0 * 15 = 105.0. Min = 105.0
Level II: Sort by Ratio + BST/TreeMap for Qualities
Intuition
As we iterate through workers sorted by ratio, we just need the smallest qualities we've seen so far. Instead of sorting all qualities at every step, we can maintain them in a sorted data structure (TreeMap in Java, multiset in C++, SortedList in Python). This reduces the cost of finding the sum of the smallest qualities to or better per step.
Detailed Dry Run
quality = [10,20,5], wage = [70,50,30], k = 2 Ratios sorted: [(2.5,20), (6.0,5), (7.0,10)]
- i=1 (ratio=6.0, q=5): BST = {5, 20}. Sum of 2 smallest = 25. Cost = 6.0 * 25 = 150.0.
- i=2 (ratio=7.0, q=10): BST = {5, 10, 20}. Sum of 2 smallest = 15. Cost = 7.0 * 15 = 105.0.
Level III: Max-Heap (Optimal)
Intuition
Why sort qualities again and again? We just need the K smallest qualities seen so far. As we iterate through the workers sorted by ratio, we can maintain a Max-Heap of size K. If we add a new quality and the heap size exceeds K, we pop the maximum quality out. This seamlessly keeps track of the sum of the K smallest qualities in O(log K) time per worker.
Detailed Dry Run
quality = [10,20,5], wage = [70,50,30], k = 2
Workers sorted: [(2.5, q:20), (6.0, q:5), (7.0, q:10)]
Wait, k=2. Max-Heap pq, quality_sum = 0
- i=0, (2.5, 20): push 20. pq=[20], sum=20. size 1 < 2. Cost: ignore.
- i=1, (6.0, 5): push 5. pq=[20,5], sum=25. size 2 == 2. Cost = 25 * 6.0 = 150.0. Min = 150.0
- i=2, (7.0, 10): push 10. sum=35. pq=[20,10,5]. size 3 > 2 -> pop max (20). sum = 35 - 20 = 15. Size is now 2. Cost = 15 * 7.0 = 105.0. Min = min(150, 105) = 105.0. Return 105.0
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.