import heapq
class Solution:
def mincostToHireWorkers(self, quality: List[int], wage: List[int], k: int) -> float:
N = len(quality)
sortedQuality = [[wage[idx] / quality[idx] , quality[idx]] for idx in range(N)]
sortedQuality.sort(key=lambda x : (x[0], x[1]))
h = []
answer = float('inf')
max_q = float('inf')
acc_q = 0
for wagePerQuality, q in sortedQuality:
max_q = -h[0] if len(h) > 0 else float('inf')
if len(h) < k or max_q > q:
acc_q += q
heapq.heappush(h, -q)
if len(h) > k:
acc_q += heapq.heappop(h)
if len(h) == k:
answer = min(answer, acc_q * wagePerQuality)
return answer
일단 문제 해석을 하자면 어떤 idx
를 기준으로 그 k
개의 worker
그룹을 만드는데 그룹에 속할 수 있는 기준은 어떤 idx
를 기준으로 어떤 조건을 만족해야 한다.
조건은 인덱스가 idx
가 아닌 인덱스 j
가 wage[idx] / quality[idx] * quality[j] / wage[j] >= 1
일때 이다.
그러면 wage[idx]/ quality[idx]
으로 배열을 만들고 오름차순으로 정렬하면 i < j
인 모든 인덱스 i, j
에 대해서 wage[j] / quality[j] * quality[i] / wage[i] >= 1
이 된다.
그 이유는 wage[j] / quality[j] * quality[j] / wage[j]
는 당연히 1이다. 그런데 quality[i] / wage[i] >= quality[j] / wage[j]
이기 때문이다.
이제 포함되는 조건을 쉽게 만족 할 수 있게 배열을 만들었으니 순회 하면서 최소값만 저장하여 마지막에 리턴하면된다.
h
에는 -q
를 작은 순대로 정렬한다. len(h)
가 k
일때 최소값을 가질 수도 있게 되기 때문에 체크해준다.h
에 포함되는 q
보다 작은 값이 등장하면 바로 최대값을 제거하고 작은 값을 넣어준다.acc_q
는 h
에 포함된 q
의 합으로 len(h)
가 k
일때 사용하기 위해 계속 해서 갱신해준다.idx
의 wagePerQuality
* (k
그룹의 quality
의 합 => acc_q
) 중에서 최소값 이다.wagePerQuality
는 최소로 만들 수 없기 때문에 acc_q
가 최소가 되게 h
힙을 잘 갱신하면 된다.