There are N
workers. The i
-th worker has a quality[i]
and a minimum wage expectation wage[i]
.html
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:git
Return the least amount of money needed to form a paid group satisfying the above conditions.github
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:ide
1 <= K <= N <= 10000
, where N = quality.length = wage.length
1 <= quality[i] <= 10000
1 <= wage[i] <= 10000
10^-5
of the correct answer will be considered correct.
这道题说是有N个员工,每一个员工有个能力值,还有个薪水指望值,如今咱们须要从中雇佣K个员工,须要知足两个条件:1. 每一个员工的薪水要和其能力值成恒定比例。2. 每一个员工的薪水不低于其指望值。让求雇佣知足要求的K个员工的最小花费是多少,博主最开始看到这题时,觉得是背包问题,又看了一下是 Hard 的难度,更加坚决了是个 DP 问题。但实际上这倒是一道贪婪算法能解决的问题,类型标签给的是堆 Heap,嗯,因缺斯汀。咱们仔细来分析分析题目中限定必须知足的两个条件,先来看第一个,说是每一个员工的薪水要和其能力值成恒定比例,意思是说假如两个员工A和B,若A的能力值是B的2倍,那么A的薪水就要是B的两倍,要雇佣的K个员工全部人的薪水和能力都是要成比例的,而这个比例必定是个恒定值,只要可以算出这个最低的薪水能力比例值,乘以K个员工的总能力值,就能够获得最少的总花费。第二个须要知足的条件是每一个员工的薪水不能低于其指望值,则每一个员工都有一个本身固定的薪水能力比例值,而须要求的那个最低的薪水能力比例值不能小于任何一个员工本身的比例值。当员工能力值越低,指望薪水越高的时候,其薪水能力比例值就越大,因此能够根据薪水能力比例值从大到小来排列员工。能够将员工的薪水能力比例值和其能力值组成 pair 对儿放到一个数组中,而后对这个数组进行排序,则默认就是对薪水能力比例值进行从小到大的排列。接下来的操做就跟以前那道 Top K Frequent Words 很是像了,这里用一个最大堆,还要用一个变量 qsum 来累加员工的能力值,先将薪水能力比例最低的员工的能力值加到 qsum 中,同时加入到最大堆中,若堆中员工总数大于K了,则将堆顶能力值最大的员工移除,由于能力值越大意味着须要付的薪水越多。若堆中员工总数等于K了,则用当前员工的薪水能力比例乘以总的能力值数获得一个总花费,用来更新结果 res。为啥这样是正确的呢?由于当前员工的薪水能力比例值是大于堆中其余全部员工的,那么乘以恒定的总能力值,得出的总薪水数必定大于等于使用其余员工的薪水能力比例值,则每一个员工可获得的薪水必定是大于等于其指望值的,这样就同时知足了两个条件,因此是符合题意的,最终更新完获得的总花费必定是最低的,参见代码以下:code
class Solution { public: double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) { double res = DBL_MAX, qsum = 0, n = quality.size(); vector<pair<double, int>> workers; priority_queue<int> pq; for (int i = 0; i < n; ++i) { workers.push_back({double(wage[i]) / quality[i], quality[i]}); } sort(workers.begin(), workers.end()); for (auto worker : workers) { qsum += worker.second; pq.push(worker.second); if (pq.size() > K) { qsum -= pq.top(); pq.pop(); } if (pq.size() == K) { res = min(res, qsum * worker.first); } } return res; } };
Github 同步地址:orm
https://github.com/grandyang/leetcode/issues/857htm
相似题目:blog
参考资料:
https://leetcode.com/problems/minimum-cost-to-hire-k-workers/