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:

  1. Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
  2. 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. 1 <= K <= N <= 10000, where N = quality.length = wage.length
  2. 1 <= quality[i] <= 10000
  3. 1 <= wage[i] <= 10000
  4. 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 题目汇总

[LeetCode] 857. Minimum Cost to Hire K Workers 雇K个工人的最小花费的更多相关文章

  1. [LeetCode] 857. Minimum Cost to Hire K Workers 雇佣K名工人的最低成本

    There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i]. Now w ...

  2. 【LeetCode】857. Minimum Cost to Hire K Workers 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/minimum- ...

  3. 857. Minimum Cost to Hire K Workers

    There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i]. Now w ...

  4. [Swift]LeetCode857. 雇佣 K 名工人的最低成本 | Minimum Cost to Hire K Workers

    There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i]. Now w ...

  5. LeetCode 1000. Minimum Cost to Merge Stones

    原题链接在这里:https://leetcode.com/problems/minimum-cost-to-merge-stones/ 题目: There are N piles of stones ...

  6. LeetCode 1130. Minimum Cost Tree From Leaf Values

    原题链接在这里:https://leetcode.com/problems/minimum-cost-tree-from-leaf-values/ 题目: Given an array arr of ...

  7. LeetCode 983. Minimum Cost For Tickets

    原题链接在这里:https://leetcode.com/problems/minimum-cost-for-tickets/ 题目: In a country popular for train t ...

  8. 雇佣K个工人的最小费用 Minimum Cost to Hire K Workers

    2018-10-06 20:17:30 问题描述: 问题求解: 问题规模是10000,已经基本说明是O(nlogn)复杂度的算法,这个复杂度最常见的就是排序算法了,本题确实是使用排序算法来进行进行求解 ...

  9. [LeetCode] 712. Minimum ASCII Delete Sum for Two Strings 两个字符串的最小ASCII删除和

    Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. ...

随机推荐

  1. C#各版本

    C#各版本 本系列文章主要整理并介绍 C# 各版本的新增功能. C# 8.0 C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发 ...

  2. C#写的WebServices可运行于树莓派

    阅读目录 Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器 Raspkate项目 演示 回到目录 Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器   最近 ...

  3. pandas 6 时间

    类 备注 创建方法 Timestamp 时刻数据 to_datetime,Timestamp DatetimeIndex Timestamp的索引 to_datetime,date_range,Dat ...

  4. js去除数组中重复的数字

    var arr = [2,1,4,3,2,4,2,3,4,2,6,5,5] var obj = {}; var arrNew = []; for(var i=arr.length-1;i>=0; ...

  5. windows下dos窗口实现持续ping显示时间保存至日志

    效果图 右击新建 ping.bat 文件(ping为文件名称,随便起),内容如下: cscript ping.vbs  127.0.0.1 -t >log.txt 127.0.0.1 修改为你自 ...

  6. BZOJ 3689: 异或之 可持久化trie+堆

    和超级钢琴几乎是同一道题吧... code: #include <bits/stdc++.h> #define N 200006 #define ll long long #define ...

  7. 2-开发共享版APP(接入指南)-设备接入说明:快速接入

    https://www.cnblogs.com/yangfengwu/p/11249674.html 该APP安装包下载链接: http://www.mnif.cn/appapk/IotDevelop ...

  8. CSPS_110

    永远不要相信出题人诸如“保证图联通”之类的鬼话. T1 最优情况一定为从LR最高的不同位以下全是1 T2 折半搜索 T3 1.我算法不是mlog^2m,最坏情况下mlogm再乘个根号m, 考试的时候没 ...

  9. 75: libreoj #10028 双向宽搜

    $des$ 实现一个bfs $sol$ 写了一个双向bfs #include <bits/stdc++.h> using namespace std; #define Rep(i, a, ...

  10. 洛谷 P1432 倒水问题

    目录 题目 思路 \(Code\) 题目 戳 思路 \(bfs\) 第一遍提交\(50\),第二遍就\(100\)了,qwq \(Code\) #include<iostream> #in ...