857. Minimum Cost to Hire K Workers

Posted tobeabetterpig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了857. Minimum Cost to Hire K Workers相关的知识,希望对你有一定的参考价值。

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 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, where N = quality.length = wage.length
1 <= quality[i] <= 10000
1 <= wage[i] <= 10000
Answers within 10^-5 of the correct answer will be considered correct.




翻译一下题目:
两个规则
每个员工的工资比例应该是他们quality的比例
=> wage[i] : wage[j] = quality[i] : quality[j]
=> wage[i] / quality[i] = wage[j] / quality[j]
最终被hire 的k个员工,他们之间的wage 和quality 关系应该是相等
2. 每个员工的工资应该高于他们的最低期望值
=> 我们想要节约成本,那么工资应该尽量靠近员工的最低期望值
=> 每个员工,他都有个expected ratio of wage compared to his quality
=>这个ratio 应该尽量小

思路一:
我们要hire k个人,那么我们就n 个人中选k 个。满足rule的同时选出cost最小的
因为每个人会keep expectation wage, 我们从每个人的expectation wage 和wage/quality 出发,尝试去构建符合条件的一组解
Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
0th person: min wage is 4, ratio is 4/3
           其他人的price 为  index 1 : 1 * 4/3= 4/3,  => wage[i] =  wage[j] / quality[j] * quality[j]
index 2: 10 * 4/3=40/3, 
index 3: 10 * 4/3 = 40/3,  
index 4: 1 * 4/3 = 4/3
           超过最低工资expectation的是index第二个人和第三个人
    所以最终选择index = 0, 2, 3 的worker => min cost = 30.66667
1st person: min wage is 8, ratio is 8/1 = 8
           其他人的price 为  index 0 : 3 * 8/1= 24, 
index 2: 10 * 8/1= 80, 
index 3: 10 * 8/1 = 80,  
index 4: 1 * 8/1 = 8
         全部超过最低工资
         最终选择 index = 0, 1, 4 => min cost = 40
……
依次枚举出来之后,我们可以看到第一个情况的min cost 最小,那么我们采用第一种情况

Time: O(n*nlogn) -- n is the number of workers,中间我们需要sort, 然后知道符合条件的前k个人是谁
Space: O(n)
For each ratio n_i  以n_i标准,   ? n
  
find the best k candidates,    1. n_j <= n_i,  && 2. quality 之和最小  ? n + nlogn
代码:
public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
        double res = Double.MAX_VALUE;
        int n = wage.length;
        for (int i = 0; i < n; i++) {
            double curRatio = (double) wage[i] / quality[i];
            double[] prices = new double[n];
            int validWorkerNum = 0;
            for (int j = 0; j < n; j++) {
                double curPrice = curRatio * quality[j];
                if (curPrice < wage[j]) continue;
                prices[validWorkerNum++] = curPrice;
            }
            if (validWorkerNum < K) continue;
            Arrays.sort(prices, 0, validWorkerNum);
            double costs = 0;
            for (int k = 0; k < K; k++) {
                costs += prices[k];
            }
            res = Math.min(res, costs);
        }
        return res;
    }

思路二:
上面的过程中,我们在尝试构建的时候, 会遇到一些不满足minium expectation的情况, 那些情况其实可以不用走。那我们再来看一下这个题目,寻找别的突破口。因为一个pay group只能有一个ratio, 那么我们就是对每个ratio找最小的k个人。我们可以对ratio先进行排序。从最小的ratio 开始,计算整个组的工资。我们可以用一个data structure去维持k 个candidates 的quality。 有了quality和ratio, 我们可以计算整一个组的工资。
公式: ratio * total quality = total wage for this group
我们用一个max priority queue来放置worker的quality。
Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
ratio: [4/3, 8/1, 2/10, 2/10, 7/1]
sorted ratio [2/10, 2/10, 4/3, 7/1, 8/1]
quality :     [10, 10, 3, 1, 1]
maxHeap:  10, 3, 1
qualitySum: 10, 20, 23, 
res = 23 * 4/3 = 30.66667
Time: O(nlogn + nlogk) 
Space: O(n)
代码:
public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
        double[][] workers = new double[quality.length][2];
        for (int i = 0; i < quality.length; i++) {
            workers[i] = new double[]{(double)wage[i] / quality[i], (double) quality[i]};
        }
        Arrays.sort(workers, (a, b) -> Double.compare(a[0], b[0]));
        double res = Double.MAX_VALUE;
        
        PriorityQueue<Double> maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b, a));
        double qualitySum = 0;
        for (double[] worker: workers) {
            maxHeap.offer(worker[1]);
            qualitySum += worker[1];
            if (maxHeap.size() == K) {
                res = Math.min(res, qualitySum * worker[0]);
                qualitySum -= maxHeap.poll();
            }
        }
        return res;
    }
}

 

以上是关于857. Minimum Cost to Hire K Workers的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 857: Minimum Cost to Hire K Workers

857. Minimum Cost to Hire K Workers

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

LeetCode 1000. Minimum Cost to Merge Stones

[LeetCode 1167] Minimum Cost to Connect Sticks

[LeetCode] 1000. Minimum Cost to Merge Stones