LeetCode 857. Minimum Cost to Hire K Workers

合法的pay group里所有worker的比例是一样的,即 wage1/wage2 = quality1/quality2

推出 wage1/quality1 = wage2/quality2。

这就好办了,定义 ratio_i = wage_i/quality_i。对于一个group,ratio一定是所有人中最大的那个。

对于一个大小为k的group,需要pay的钱就是 Σ_k quality_i * 最大的ratio。

为了避免每次扫一遍group找到最大的ratio,我们根据ratio排序,根据ratio从小到大考虑。同时我们建立一个大小为k的大顶堆,并保证当前堆里的元素除了当前ratio,是最小的k-1个元素。

和 top k 问题用小顶堆一样,这里用大顶堆可以找到最小的k个元素,从而这k个元素的和也是最小的。

class Solution {
public:
    struct Worker {
        int quality, wage;
        double ratio;
        Worker(int q, int w):quality(q),wage(w){
            ratio = double(wage)/quality;
        }
    };
    
    double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) {
        int n=quality.size();
        vector<Worker> vec;
        for (int i=0;i<n;++i){
            vec.push_back(Worker(quality[i],wage[i]));
        }
        sort(vec.begin(),vec.end(),[](const Worker &a, const Worker &b){
            return a.ratio<b.ratio;
        });
        
        // max heap accourding to quality
        auto cmp=[](const Worker &a, const Worker &b){
            return a.quality < b.quality;
        };
        priority_queue<Worker,vector<Worker>,decltype(cmp)> q(cmp);
        
        double sum=0, res=INT_MAX; // sum - sum of quality
        for (Worker worker:vec){
            if (q.size()>=K){
                sum -= q.top().quality;
                q.pop();
            }
            q.push(worker);
            sum += worker.quality;
            
            if (q.size()==K) 
                res=min(res, sum*worker.ratio);
        }
        
        return res;
    }
};

时间复杂度 O(nlogn)

转载于:https://www.cnblogs.com/hankunyan/p/11485028.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值