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個工人,第i個工人的質量是quality[i],最小工資期盼是wage[i],現在想雇K個工人組成一個支付組,返回所需的最小花費。有兩個條件:
1. K個工人的質量和給他開的工資的比例是相同的。
2. 每個工人都要滿足他的最小期望工資。
解法:最大堆, heapq, PriorityQueue。首先對付工資和質量的比率進行排序wage/quality,同時記錄quality,也就是(wage/quality, quality),代表一個工人情況,比率越大說明工人效率越低。選定的K個人最后要按照相同的比率來支付工資,為了保證每個人的最低工資標准,只能選定比率最高的人的比率來支付工資。每個人的支付工資:wage = ratio * quality,總的支付工資:total wage = ratio * total quality,在ratio相同的情況小,總的quality越小越好。用一個變量result記錄最小花費,初始為最大浮點數。循環排序好的工資比率,用一個變量qsum累加quality,用一個最大堆記錄當前的quality,堆頂是最大的quality,如果堆長度等於K+1,就彈出quality最大的,同時qsum中去掉這個最大值。堆滿足K個工人的時候,每次都計算qsum * ratio,和result比較取小的。
Java:
public double mincostToHireWorkers(int[] q, int[] w, int K) { double[][] workers = new double[q.length][2]; for (int i = 0; i < q.length; ++i) workers[i] = new double[]{(double)(w[i]) / q[i], (double)q[i]}; Arrays.sort(workers, (a, b) -> Double.compare(a[0], b[0])); double res = Double.MAX_VALUE, qsum = 0; PriorityQueue<Double> pq = new PriorityQueue<>(); for (double[] worker: workers) { qsum += worker[1]; pq.add(-worker[1]); if (pq.size() > K) qsum += pq.poll(); if (pq.size() == K) res = Math.min(res, qsum * worker[0]); } return res; }
Python:
def mincostToHireWorkers(self, quality, wage, K): workers = sorted([float(w) / q, q] for w, q in zip(wage, quality)) res = float('inf') qsum = 0 heap = [] for r, q in workers: heapq.heappush(heap, -q) qsum += q if len(heap) > K: qsum += heapq.heappop(heap) if len(heap) == K: res = min(res, qsum * r) return res
Python:
# Time: O(nlogn) # Space : O(n) import itertools import heapq class Solution(object): def mincostToHireWorkers(self, quality, wage, K): """ :type quality: List[int] :type wage: List[int] :type K: int :rtype: float """ workers = [[float(w)/q, q] for w, q in itertools.izip(wage, quality)] workers.sort() result = float("inf") qsum = 0 max_heap = [] for r, q in workers: qsum += q heapq.heappush(max_heap, -q) if len(max_heap) > K: qsum -= -heapq.heappop(max_heap) if len(max_heap) == K: result = min(result, qsum*r) return result
Python: O(nlogn) time,O(n) space
class Solution(object): def mincostToHireWorkers(self, quality, wage, K): """ :type quality: List[int] :type wage: List[int] :type K: int :rtype: float """ # 按比例排序,nlogn workers = sorted([float(wage[i])/quality[i], quality[i]] for i in range(len(quality))) res,qsum = float('inf'),0 heap = [] for i in range(len(workers)): # 選定比例 r r,q = workers[i] heapq.heappush(heap,-q) # qsum始終記錄k個人的quality之和,乘以r即為最后結果 qsum += q if len(heap) > K: # 始終丟棄quality最大的人 qsum += heapq.heappop(heap) if len(heap) == K: res = min(res, qsum * r) return res
C++:
double mincostToHireWorkers(vector<int> q, vector<int> w, int K) { vector<vector<double>> workers; for (int i = 0; i < q.size(); ++i) workers.push_back({(double)(w[i]) / q[i], (double)q[i]}); sort(workers.begin(), workers.end()); double res = DBL_MAX, qsum = 0; priority_queue<int> pq; for (auto worker: workers) { qsum += worker[1], pq.push(worker[1]); if (pq.size() > K) qsum -= pq.top(), pq.pop(); if (pq.size() == K) res = min(res, qsum * worker[0]); } return res; }
C++:
// Time: O(nlogn) // Space: O(n) class Solution { public: double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) { vector<pair<double, int>> workers; for (int i = 0; i < quality.size(); ++i) { workers.emplace_back(static_cast<double>(wage[i]) / quality[i], quality[i]); } sort(workers.begin(), workers.end()); auto result = numeric_limits<double>::max(); auto sum = 0.0; priority_queue<int> max_heap; for (const auto& worker: workers) { sum += worker.second; max_heap.emplace(worker.second); if (max_heap.size() > K) { sum -= max_heap.top(), max_heap.pop(); } if (max_heap.size() == K) { result = min(result, sum * worker.first); } } return result; } };
All LeetCode Questions List 題目匯總