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.
题目理解:
给定n个工人,每个工人有自己的工作能力,以及最低工资标准,需要招聘K个工人,每个工人得到工资必须与他们之间的工作能力成正比,而且不能低于每个人的最低工资标准,问花的钱最少是多少。
解题思路:
题目中说,工资必须要与工作能力成正比,也就是说,每个工人的工资是一个常数p与其工作能力的乘积;那么为了花最少的钱,我们一定会选一个最小的常数p,这个p其实就是每个工人的单位工作能力的价格;因为不能低于最低工资标准,所以我们一定要选择全部K个工人当中的最大的p,才能使得工资不低于所有人各自的最低工资标准;
在选定某一个p之后,我们选出来单位工作能力价格小于或者等于p的所有工人,在这些工人当中选出工作能力最低的K个工人,花费的价格就是就是在当前p的条件下最低的费用,我们遍历所有的p之后,就能得到最低花费。
代码如下:
class Solution {
class node implements Comparable<node>{
int quality;
double price;
public node(int q, double p) {
quality = q;
price = p;
}
@Override
public int compareTo(node a) {
// TODO Auto-generated method stub
if(Math.abs(this.price - a.price) < 0.000001)
return 0;
return this.price < a.price ? -1 : 1;
}
}
public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
int len = quality.length;
List<node> list = new ArrayList<node>();
for(int i = 0; i < len; i++) {
list.add(new node(quality[i], 1.0 * wage[i] / quality[i]));
}
Collections.sort(list);
double res = Double.MAX_VALUE;
int sum = 0;
PriorityQueue<Integer> qu = new PriorityQueue<Integer>(Collections.reverseOrder());
for(node it : list) {
sum += it.quality;
qu.offer(it.quality);
if(qu.size() > K) {
sum -= qu.poll();
}
if(qu.size() == K) {
res = Math.min(res, sum * it.price);
//System.out.println(sum + " " + res);
}
}
return res;
}
}