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/