LeetCode[Hard]------857. Minimum Cost To Hire K Workers

版权声明:版权归博主CodingArtist所有,转载请标明出处。 https://blog.csdn.net/sc19951007/article/details/83684434

问题描述

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.


简单翻译一下,现在要雇佣K名工人,每个工人有自己的能力值quality和对期望的薪水wage,但是他们实际的薪水必须满足两个条件

  1. 实际薪水必须和他们的能力成正比。
  2. 每个被雇佣的工人必须满足他们最低的薪水期望

要求返回雇佣K个工人最小的支付薪水。

思路:

首先要对题目所给的rules有精确的理解,简单来说就是1份quality,1份wage,而且每个人都有满足其最小wage expectation。

我的第一印象是按wage大小对workers进行排序,把最小的K个wage的加起来即可,因为题目中没有对quality的限制。但这么想的话根本就是个easy问题。再三考虑之后发现,发钱时并不是按wage数组发的,而是和wage/quality这个比值有关。因为根据rule1,worker i,j 的quality[i]:quality[j] == wage[i]: wage[j]的,因此 quality[i]:wage[i] == quality[j]:wage[j],也就是说wage/quality 的ratio对于每个worker来说都一样!!

于是我有了思路,通过这个ratio构建worker数组,并从小到大sort,然后我们取前K个worker,他们的ratio必须是ratio最大的那个 worker的,也就是最近取的那个worker,此时的wage总和就是总的quality × 最近取的worker的ratio。

做到这里感觉程序就可以结束了,因为ratio这里是最小的。但是如果我们继续遍历worker,ratio虽然增大但是quality的总和可能会减小。所以我们需要遍历所有worker,保证hire window的size始终为K。

问题又来了,如何保证K个worker的quality在遍历时持续remove最大的quality? PriorityQueue 可以完美解决这个问题,只需要add进负的worker quality,此时poll出的就是最大的quality。

代码:

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, qsum = 0;
        PriorityQueue<Double> l = new PriorityQueue<>();
        for (double[] worker: workers) {
            qsum += worker[1];
            l.add(-worker[1]);
            if (l.size() > K) qsum += l.poll();
            if (l.size() == K) res = Math.min(res, qsum * worker[0]);
        }
        return res;
    }      

仅用于个人的学习理解,如需转载,请标明出处:
https://blog.csdn.net/sc19951007/article/details/83684434

猜你喜欢

转载自blog.csdn.net/sc19951007/article/details/83684434