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. ReentrantReadWriteLock中的锁降级

    锁降级指的是写锁降级为读锁. 因为读锁与读锁之间不互斥,如果是写锁与读锁或者是写锁与写锁就会互斥,所以由写锁变为读锁就降级了. 如果当前线程拥有写锁,然后将其释放,最后再获取读锁,这种并不能称之为锁降 ...

  2. Apache虚拟主机&伪静态配置

    Apache基本操作 安装:yum install httpd 启动:systemctl start httpd 查看进程:ps -ef | grep httpd 查看端口:sudo netstat ...

  3. 网站安全DDOS攻击及监测

    一. 监测 在类Unix系统中可以使用top查看系统资源.进程.内存占用等信息.查看网络状态可以使用netstat.nmap等工具.若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop ...

  4. node 日志 log4js 错误日志记录

    SET DEBUG=mylog:* & npm start 原文出处:http://blog.fens.me/nodejs-log4js/ 1. 默认的控制台输出 我们使用express框架时 ...

  5. 自动化发送邮件之SMTP

    一.思路 1.若是QQ邮箱需要在设置-账户里面开启服务 2.在python中smtplib库是专门用来处理邮件 3.自动化邮件发送实操 a.要处理的邮件主题,寄件人,收件人,邮件正文,附件, b.邮件 ...

  6. HDU-2196-Computer(树上DP)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=2196 题意: A school bought the first computer some time ...

  7. SVN 常用 还原项目

    1.先修改本来两个文件,然后再提交到SVN 2.在日志界面,查看提交的文件,找到对应的版本号 3.找到对应的版本号(这里的版本号是1995,我提交生成的版本号 的前一个版本 才是我未作出修改的版本), ...

  8. 计蒜客 39279.Swap-打表找规律 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest L.) 2019ICPC西安邀请赛现场赛重现赛

    Swap There is a sequence of numbers of length nn, and each number in the sequence is different. Ther ...

  9. CDH 版本 6.0.1 升级到 6.2.0 当前最新版本(CentOS 7.x)

    前文「CDH CM版本 6.0.1 升级到 CM 6.2.0 当前最新版本(CentOS 7.x)」 承接上文,当我们完成 CM 6.2.0 的升级之后,我们已经相当于完成了80% minor 的升级 ...

  10. Flask報錯 KeyError 'SQLALCHEMY_TRACK_MODIFICATIONS'.md

    KeyError: 'SQLALCHEMY_TRACK_MODIFICATIONS' 关于flask-sqlalchemy中出现的 KeyError: 'SQLALCHEMY_TRACK_MODIFI ...