2024-5-2——雇佣 K 名工人的最低成本

题目来源

力扣每日一题;题序:857

我的题解

方法一 贪心+优先队列

参考灵神
关键点1:只有有一个工人刚好获得其最低期望薪资。因为,若所有工人都获得比自己最低期望薪资高,那么可以降低工人工资以实现更低的成本。
关键点2:找到,工人i的工作效率r=wage[i]/quality[i],若以某人的 r i r_i ri为基准发工资,那么对于 r 值不超过 r i r_i ri的工人,发给他们的工资是不低于其最低期望工资的,因此这些工人是可以随意选择(雇佣)的
关键点3:如何在从小到大枚举 r i r_i ri时,维护当前最小的 k 个 quality 值?使用最大堆来维护。按照 r i r_i ri从小到大的顺序遍历工人,当堆中有 k 个元素时,如果 qualityi比堆顶小,则可以弹出堆顶,将 quality i \textit{quality}_i qualityi入堆,从而得到一个更小的 sumQ,此时有可能找到一个更优解 sumQ ⋅ r i \textit{sumQ}\cdot r_i sumQri,更新答案。

时间复杂度:O(nlogn),其中 n 为 quality 的长度。排序的时间复杂度为 O(nlog⁡n),后面和堆有关的时间复杂度为 O(nlog⁡k),由于 k≤n,总的时间复杂度为 O(nlog⁡n)。
空间复杂度:O(n)

public double mincostToHireWorkers(int[] quality, int[] wage, int k) {
    int n=quality.length;
    Integer[] idx=new Integer[n];
    Arrays.setAll(idx,i->i);
    Arrays.sort(idx,(a,b)->quality[b]*wage[a]-quality[a]*wage[b]);
    double res=0;
    double sumQ=0;
    PriorityQueue<Integer> pq=new PriorityQueue<>((a,b)->b-a);
    for(int i=0;i<k;i++){
        sumQ+=quality[idx[i]];
        pq.offer(quality[idx[i]]);
    }
    res=sumQ*((double)wage[idx[k-1]]/quality[idx[k-1]]);
    for(int i=k;i<n;i++){
        int q=quality[idx[i]];
        if(q<pq.peek()){
            sumQ-=pq.poll()-q;
            pq.offer(q);
            res=Math.min(res,sumQ*((double)wage[idx[i]]/q));
        }
    }
    return res;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的小彭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值