美文网首页
【教3妹学算法-leetcode】雇佣 K 名工人的最低成本

【教3妹学算法-leetcode】雇佣 K 名工人的最低成本

作者: 程序员小2 | 来源:发表于2022-07-18 22:33 被阅读0次

    插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
    坚持不懈,越努力越幸运,大家一起学习鸭~~~

    3妹

    3妹:2哥,你到公司了吗,我的电脑充电器忘记带了,呜呜。
    2哥:哈哈,谁让你总是丢三落四的。
    3妹:哎,又要跑回去拿了。
    2哥:这么热的天别回去了吧,你和你同事共用一个,一会儿她用一会儿你用不就可以了。
    3妹:对哦,我和我同事商量下。
    2哥:要学会线程切换,让她让出CPU,哈哈。
    3妹:2哥就是2哥,厉害的。

    讲课

    题目:

    有 n 名工人。 给定两个数组 quality 和 wage ,其中,quality[i] 表示第 i 名工人的工作质量,其最低期望工资为 wage[i] 。

    现在我们想雇佣 k 名工人组成一个工资组。在雇佣 一组 k 名工人时,我们必须按照下述规则向他们支付工资:

    对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
    工资组中的每名工人至少应当得到他们的最低期望工资。
    给定整数 k ,返回 组成满足上述条件的付费群体所需的最小金额 。在实际答案的 10-5 以内的答案将被接受。。

    示例 1:

    输入: quality = [10,20,5], wage = [70,50,30], k = 2
    输出: 105.00000
    解释: 我们向 0 号工人支付 70,向 2 号工人支付 35。
    示例 2:

    输入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
    输出: 30.66667
    解释: 我们向 0 号工人支付 4,向 2 号和 3 号分别支付 13.33333。

    提示:

    n == quality.length == wage.length
    1 <= k <= n <= 104
    1 <= quality[i], wage[i] <= 104

    思路:

    堆(优先队列)
    我们可以定义一个“价值”,表示工人最低期望工资与工作质量之比。例如某位工人的最低期望工资为 100,工作质量为 20,那么他的价值为 100 / 20 = 5.0。

    可以发现,如果一名工人的价值为 R,当他恰好拿到最低期望工资时,如果所有价值高于 R 的工人都无法拿到最低期望工资,而所有价值低于 R 的工人都拿得比最低期望工资多。因此,我们可以按照这些工人的价值,对他们进行升序排序。排序后的第 i 名工人可以在它之前任选 K - 1 名工人,并计算对应的工资总和,为 R * sum(quality[c1] + quality[c2] + ... + quality[c{k-1}] + quality[i]),也就是说,我们需要在前 i 名工人中选择 K 个工作质量最低的。我们可以使用一个大根堆来实时维护 K 个最小值。

    java代码:

    class Solution {
        public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
            int N = quality.length;
            Worker[] workers = new Worker[N];
            for (int i = 0; i < N; ++i)
                workers[i] = new Worker(quality[i], wage[i]);
            Arrays.sort(workers);
    
            double ans = 1e9;
            int sumq = 0;
            PriorityQueue<Integer> pool = new PriorityQueue();
            for (Worker worker: workers) {
                pool.offer(-worker.quality);
                sumq += worker.quality;
                if (pool.size() > K)
                    sumq += pool.poll();
                if (pool.size() == K)
                    ans = Math.min(ans, sumq * worker.ratio());
            }
    
            return ans;
        }
    }
    
    class Worker implements Comparable<Worker> {
        public int quality, wage;
        public Worker(int q, int w) {
            quality = q;
            wage = w;
        }
    
        public double ratio() {
            return (double) wage / quality;
        }
    
        public int compareTo(Worker other) {
            return Double.compare(ratio(), other.ratio());
        }
    }
    

    相关文章

      网友评论

          本文标题:【教3妹学算法-leetcode】雇佣 K 名工人的最低成本

          本文链接:https://www.haomeiwen.com/subject/hbclirtx.html