Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit afabb87

Browse files
author
robot
committed
feat: 2024-04
1 parent 97c8821 commit afabb87

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

‎thinkings/heap-2.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,22 @@ class MedianFinder:
236236

237237
题目要求我们选择 k 个人,按其工作质量与同组其他工人的工作质量的比例来支付工资,并且工资组中的每名工人至少应当得到他们的最低期望工资。
238238

239-
换句话说,同一组的 k 个人他们的工作质量和工资比是一个固定值才能使支付的工资最少。请先理解这句话,后面的内容都是基于这个前提产生的
239+
由于题目要求我们同一组的工作质量与工资比值相同。因此如果 k 个人中最大的 w/q 确定,那么总工资就是确定的。就是 sum_of_q * w/q, 也就是说如果 w/q 确定,那么 sum_of_q 越小,总工资越小
240240

241-
我们不妨定一个指标**工作效率**,其值等于 q / w。前面说了这 k 个人的 q / w 是相同的才能保证工资最少,并且这个 q / w 一定是这 k 个人最低的(短板),否则一定会有人得不到最低期望工资。
241+
又因为 sum_of_q 一定的时候, w/q 越小,总工资越小。因此我们可以从小到大枚举 w/q,然后在其中选 k 个 最小的q,使得总工资最小。
242+
243+
因此思路就是:
244+
245+
- 枚举最大的 w/q, 然后用堆存储 k 个 q。当堆中元素大于 k 个时,将最大的 q 移除。
246+
- 由于移除的时候我们希望移除"最大的"q,因此用大根堆
242247

243248
于是我们可以写出下面的代码:
244249

245250
```py
246251
class Solution:
247252
def mincostToHireWorkers(self, quality: List[int], wage: List[int], K: int) -> float:
248-
eff = [(q / w, q, w) for a, b in zip(quality, wage)]
249-
eff.sort(key=lambda a: -a[0])
253+
eff = [(w/q, q, w) for q, w in zip(quality, wage)]
254+
eff.sort(key=lambda a: a[0])
250255
ans = float('inf')
251256
for i in range(K-1, len(eff)):
252257
h = []
@@ -255,7 +260,7 @@ class Solution:
255260
# 找出工作效率比它高的 k 个人,这 k 个人的工资尽可能低。
256261
# 由于已经工作效率倒序排了,因此前面的都是比它高的,然后使用堆就可得到 k 个工资最低的。
257262
for j in range(i):
258-
heapq.heappush(h, eff[j][1] / rate)
263+
heapq.heappush(h, eff[j][1] * rate)
259264
while k > 0:
260265
total += heapq.heappop(h)
261266
k -= 1
@@ -280,18 +285,19 @@ class Solution:
280285
```py
281286
class Solution:
282287
def mincostToHireWorkers(self, quality: List[int], wage: List[int], K: int) -> float:
283-
effs = [(q / w, q) for q, w in zip(quality, wage)]
284-
effs.sort(key=lambda a: -a[0])
285-
ans = float('inf')
288+
# 如果最大的 w/q 确定,那么总工资就是确定的。就是 sum_of_q * w/q, 也就是说 sum_of_q 越小,总工资越小
289+
# 枚举最大的 w/q, 然后用堆在其中选 k 个 q 即可。由于移除的时候我们希望移除"最大的"q,因此用大根堆
290+
A = [(w/q, q) for w, q in zip(wage, quality)]
291+
A.sort()
292+
ans = inf
293+
sum_of_q = 0
286294
h = []
287-
total = 0
288-
for rate, q in effs:
295+
for rate, q in A:
289296
heapq.heappush(h, -q)
290-
total += q
291-
if len(h) > K:
292-
total += heapq.heappop(h)
297+
sum_of_q += q
293298
if len(h) == K:
294-
ans = min(ans, total / rate)
299+
ans = min(ans, sum_of_q * rate)
300+
sum_of_q += heapq.heappop(h)
295301
return ans
296302
```
297303

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /