码迷,mamicode.com
首页 > 其他好文 > 详细

857. Minimum Cost to Hire K Workers

时间:2018-09-17 12:33:15      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:array   超过   ++   pac   form   where   person   ini   sid   

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

标签:array   超过   ++   pac   form   where   person   ini   sid   

原文地址:https://www.cnblogs.com/tobeabetterpig/p/9661334.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!