一、想不出思路,看官方题解
我的理解:
-
“对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。”将这句话翻译为:
“当固定了某K个工人为一组时,工人k1的质量q1作分子,质量和totalq作分母,再乘以总的发的工资totalw,就是他能拿到的工资w1”,这个w1必须大于等于他期望的工资,才是合理的分组。 -
将不等式变换下,可知最小分发工资的影响因素为(组里最大的性价比w/q)、以及(总质量)。
-
贪心:先将所有小的性价比员工放进来(卷的员工,质量高、钱要的还少),然后枚举以每一个能成为工资组中权重(性价比)最大的工人(固定一个变量,剔除质量太高的)来计算最小工资组开销,然后取其中的最小即可。
python 函数
- zip() :将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象
- sorted():使用 sorted() 函数对序列进行排序, 并不会在原序列的基础进行修改,而是会重新生成一个排好序的列表。
代码
class Solution:
def mincostToHireWorkers(self, quality: List[int], wage: List[int], k: int) -> float:
# 将每个员工按性价比(wage/quality)从小到大排序
# 越小,说明取得是质量高、期待工资还低的员工,卷的员工
ratio = sorted(zip(quality, wage), key = lambda p: p[1] / p[0])
totalq = 0
# res = 0
res = inf
# 堆,存放quality质量,按照推理的公式,totalq越小越好,所以构建大根堆,每次优先去掉质量高的
Qheap = []
# i = 0
for qua, wage in ratio[:k-1]: # 取前k-1个
totalq += qua
heappush(Qheap, -qua) # 默认构建小根堆,取负使得大根堆
# i += 1
# if i == k:
# res = wage / qua * totalq # 最后的结果,最小给与的工资就是该等式
for qua, wage in ratio[k-1:]:
# 确定当前工人为最大性价比的时候,最小工资只与其性价比和总质量有关
totalq += qua
heappush(Qheap, -qua)
res = min(res, wage/qua * totalq)
#去掉质量最高的
totalq += heappop(Qheap) # 取出来是负值,相当于将去最高质量的工人
return res