版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_41855420,未经博主允许不得转载。 https://blog.csdn.net/qq_41855420/article/details/90899961
有 N 名工人。 第 i 名工人的工作质量为 quality[i] ,其最低期望工资为 wage[i] 。
现在我们想雇佣 K 名工人组成一个工资组。在雇佣 一组 K 名工人时,我们必须按照下述规则向他们支付工资:
对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
工资组中的每名工人至少应当得到他们的最低期望工资。
返回组成一个满足上述条件的工资组至少需要多少钱。
示例 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。
提示:
1 <= K <= N <= 10000,其中 N = quality.length = wage.length
1 <= quality[i] <= 10000
1 <= wage[i] <= 10000
与正确答案误差在 10^-5 之内的答案将被视为正确的。
首先我们计算每个工人的性价比costPerformance(即预期工资wage[i] / 工作质量 quality[i],也即单位工作量的价格),因此costPerformance越低表示性价比越高。
然后按照 单位工作量的价格 进行升序排序。并且使用辅助优先队列,选出K名工人。
假设K名工人的工作质量总和为sum,而我们又要满足所选工人的工资不得低于各自的预期,则costPerformance应该取这K名工人的最大值(性价比最低)来计算总工资sum * costPerformance。
并且当costPerformance一定时,我们得使工作质量总和为sum尽可能的小,才能降低总工资。
//自定义工人结构体
struct MyWorker{
int quality;//质量
double costPerformance;//性价比:单位工作质量需要的价格(性价比越高,数值越小)
MyWorker(int _quality, double _costPerformance){
quality = _quality;
costPerformance = _costPerformance;
}
//重载小于号,用于按照 性价比:单位工作质量需要的价格 升序排序
bool operator < (const MyWorker &myWorker){
return costPerformance < myWorker.costPerformance;
}
};
class Solution {
public:
double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) {
int N = quality.size();
vector<MyWorker> myWorkerVec;//存储所有工人的信息
for (int i = 0; i < N; ++i){
myWorkerVec.push_back(MyWorker(quality[i], 1.0 * wage[i] / quality[i]));
}
sort(myWorkerVec.begin(), myWorkerVec.end());//按照性价比递减排序(性价比越高,数值越小)
double result = INT_MAX, sum = 0;
priority_queue<int> maxHeap;//大顶堆
//从性价比高的工人向性价比低的工人扫描
for (const auto& worker: myWorkerVec) {
sum += worker.quality;//worker的工作质量放入总工作质量
maxHeap.emplace(worker.quality);//worker的工作质量放入优先队列
//如果工人超过了K,则移除最大工作量的工人(即优先队列的顶端)
if (maxHeap.size() > K) {
sum -= maxHeap.top();
maxHeap.pop();
}
//由于扫描过程是从性价比高的工人向性价比低的工人扫描,并且我们得不低于每个人的预期工资,
//所以得按照最低性价比(单位工作质量需要的最高价格),就是当前最后一名工人worker的性价比计算总工资
if (maxHeap.size() == K) {
result = min(result, sum * worker.costPerformance);
}
}
return result;
}
};
性价比的概念可能会有些绕,只要记住它的本质是 “单位工作量的价格” 就比较好理解。