Leetcode857.雇佣 K 名工人的最低成本

题目链接

点我(^_^)


题目大意


比如有 3 个工人,我们要组成 2 个人的工资组,其工作质量数组为[10,20,5],最低期望工资数组为[70,50,30],那么可以证明选择 0 号工人支付70,2 号工人支付35为最优解。


解题思路

这里假定总花费为 totalc,工资组工作质量总和为 totalq,那么如果一个工人在工资组中,其应该满足如下条件:

可以转化为:

在这里插入图片描述

我们的目的是需要找到最小的 totalc,那么可以进行贪心选择,我们将 wagei/qualityi 定义为性价比 pqratioi,pqratioi是确定的,那么如果我们现在确定一个工人 i,其作为工资组性价比上限,那么只需要寻找性价比小于等于上限的即可,且 totalq 越小越好,那么就寻找 k-1 个满足性价比要求的最小的工作质量的工人即可。

这样我们可以先用性价比对工人从小到大排序,然后从第k-1(从0开始编号)个工人开始,其性价比作为工资组的性价比工资上线,再从前面选出 k-1 个满足性价比条件的且工作质量最小的工人,这个可以使用大根堆维护。每次更新答案即可,答案最大可能到 1e8(1e4*1e4)

代码(C++)

class Solution {
public:
    double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {
        int n = quality.size();
        vector<int> idx(n);
        iota(idx.begin(), idx.end(), 0); // [0,1,2,...,n-1]
        sort(idx.begin(), idx.end(), [&](int& a, int& b) {
            return quality[a] * wage[b] > quality[b] * wage[a];
        });
        double ans = 1e8;
        double totalq = 0.0;
        priority_queue<int, vector<int>, less<int>> q;
        for (int i = 0; i < k - 1; i++) {
            totalq += quality[idx[i]];
            q.push(quality[idx[i]]);
        }
        for (int i = k - 1; i < n; i++) {
            int id = idx[i];
            totalq += quality[id];
            q.push(quality[id]);
            double totalc = ((double) wage[id] / quality[id]) * totalq;
            ans = min(ans, totalc);
            totalq -= q.top();
            q.pop();
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值