• [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 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 题目汇总

  • 相关阅读:
    解决 JDK1.7 不支持 VCenter 6.7 的问题(涉及到Https TLS1.2协议)
    无法删除另一个分区的windows文件夹
    首次将项目从eclipse提交到服务器的SVN
    无法截图右键菜单
    配置文件无法修改(以修改my-default.ini为例)
    运行JavaWeb项目报错Access denied for user 'root'@'localhost' (using password: YES)
    jquery.page.js插件在使用时重复触发“上一页”和“下一页”操作
    请求ajax失败的原因(进入到error)
    ajax请求执行完成后再执行其他操作(jQuery.page.js插件使用为例)
    img标签src资源无法加载,报net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION错
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9795918.html
Copyright © 2020-2023  润新知