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個員工,需要滿足兩個條件:1. 每個員工的薪水要和其能力值成恆定比例。2. 每個員工的薪水不低於其期望值。讓求雇佣滿足要求的K個員工的最小花費是多少,博主最開始看到這題時,以為是背包問題,又看了一下是 Hard 的難度,更加堅定了是個 DP 問題。但實際上這卻是一道貪婪算法能解決的問題,類型標簽給的是堆 Heap,嗯,因缺斯汀。我們仔細來分析分析題目中限定必須滿足的兩個條件,先來看第一個,說是每個員工的薪水要和其能力值成恆定比例,意思是說假如兩個員工A和B,若A的能力值是B的2倍,那么A的薪水就要是B的兩倍,要雇佣的K個員工所有人的薪水和能力都是要成比例的,而這個比例一定是個恆定值,只要能夠算出這個最低的薪水能力比例值,乘以K個員工的總能力值,就可以得到最少的總花費。第二個需要滿足的條件是每個員工的薪水不能低於其期望值,則每個員工都有一個自己固定的薪水能力比例值,而需要求的那個最低的薪水能力比例值不能小於任何一個員工自己的比例值。當員工能力值越低,期望薪水越高的時候,其薪水能力比例值就越大,所以可以根據薪水能力比例值從大到小來排列員工。可以將員工的薪水能力比例值和其能力值組成 pair 對兒放到一個數組中,然后對這個數組進行排序,則默認就是對薪水能力比例值進行從小到大的排列。接下來的操作就跟之前那道 [Top K Frequent Words](http://www.cnblogs.com/grandyang/p/7689927.html) 非常像了,這里用一個最大堆,還要用一個變量 qsum 來累加員工的能力值,先將薪水能力比例最低的員工的能力值加到 qsum 中,同時加入到最大堆中,若堆中員工總數大於K了,則將堆頂能力值最大的員工移除,因為能力值越大意味着需要付的薪水越多。若堆中員工總數等於K了,則用當前員工的薪水能力比例乘以總的能力值數得到一個總花費,用來更新結果 res。為啥這樣是正確的呢?因為當前員工的薪水能力比例值是大於堆中其他所有員工的,那么乘以恆定的總能力值,得出的總薪水數一定大於等於使用其他員工的薪水能力比例值,則每個員工可得到的薪水一定是大於等於其期望值的,這樣就同時滿足了兩個條件,所以是符合題意的,最終更新完得到的總花費一定是最低的,參見代碼如下:
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 同步地址:
https://github.com/grandyang/leetcode/issues/857
類似題目:
參考資料:
https://leetcode.com/problems/minimum-cost-to-hire-k-workers/
[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)