There are N
workers. The i
-th worker has a quality[i]
and a minimum wage expectation wage[i]
.
Now we want to hire exactly K
workers to form a paid group. When hiring 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.
Example 1:
Input: quality = [10,20,5], wage = [70,50,30], K = 2
Output: 105.00000
Explanation: We pay 70 to 0-th worker and 35 to 2-th worker.
Example 2:
Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
Output: 30.66667
Explanation: We pay 4 to 0-th worker, 13.33333 to 2-th and 3-th workers seperately.
Note:
1 <= K <= N <= 10000
, whereN = quality.length = wage.length
1 <= quality[i] <= 10000
1 <= wage[i] <= 10000
- Answers within
10^-5
of the correct answer will be considered correct.
根据rule1,工资应该与工作质量成正比,所以w[i]/q[i] = w[j]/q[j]。可以求出每个员工的w[i]/q[i] ratio,并排序。维护一个max heap,按quality排序。按ratio从小到大的顺序,依次向heap中添加quality,并累计quality sum。当heap的size大于K时,应该poll quality最高的员工(因为总工资 = current ratio * quality sum)。poll完,heap的size等于K时,记录一下此时的cost,并与前一步的cost比较,取最小值。遍历完全部ratio后,min cost就是答案。
注意:ratio的计算和处理,double的位置
时间:O(NlogN)+O(NlogK) 排序和堆
class Solution { public double mincostToHireWorkers(int[] quality, int[] wage, int K) { double[][] worker = new double[wage.length][2]; for(int i = 0; i < wage.length; i++) { worker[i][0] = (double) wage[i] / quality[i]; worker[i][1] = quality[i]; } Arrays.sort(worker, (a, b) -> Double.compare(a[0], b[0])); PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a); double min_cost = Integer.MAX_VALUE; int qsum = 0; for(double[] w : worker) { maxHeap.add((int)w[1]); qsum += w[1]; if(maxHeap.size() > K) { int tmp = maxHeap.poll(); qsum -= tmp; } if(maxHeap.size() == K) { min_cost = Math.min(min_cost, w[0] * qsum); } } return min_cost; } }