최소 힙에선 부모가 자식보다 작아야 하고(루트=최소값), 최대 힙에선 부모가 자식보다 커야 함(루트=최댓값)
항상 정렬된 상태로 추가되고 삭제됨 -> 첫번째 원소가 최소값
# 파이썬은 최대힙은 제공하지 않음 -> 원소의 부호를 바꿔서 최대힙 구현
import heapq
# 원소 추가하기
heapq.heappush(minHeap, newValue)
heapq.heappush(minHeap, [arr[i][1], arr[i][0]])
# 원소 삭제하기
heapq.heappop(minHeap)
💡 힙에 같은 값이 입력될 경우 항상 주의
https://www.acmicpc.net/problem/1202
상덕이가 털 보석점에는 보석이 총 N개 있다. 각 보석은 무게 M와 가격 V를 가지고 있다. 상덕이는 가방을 K개 가지고 있고, 각 가방에 담을 수 있는 최대 무게는 C이다. 각 가방에는 한 개의 보석만 넣을 수 있다.
상덕이가 훔칠 수 있는 보석의 최대가격은?
for _ in range(n):
a, b = map(int, input().split())
heapq.heappush(jewel, [a, -b]) # [무게, -가격] -> 무게 작은 순, 가격 높은 순
bag = []
for _ in range(k):
bag.append(int(input())) # 각 가방에 담을 수 있는 최대 무게
bag.sort() # 가방 무게 가벼운 순
steal = []
answer = 0
for i in range(k): # 각 가방 별로
while jewel:
temp = heapq.heappop(jewel)
if bag[i] >= temp[0]: # 이 가방에 보석을 담을 수 있으면
heapq.heappush(steal, temp[1]) # 가격만 힙에 담아줌 -> temp[1]은 음수라 그대로 넣어줌(최대힙이 됨!)
else: # 담을 수 없으면 다시 넣어줌
heapq.heappush(jewel, temp)
break
if len(steal) != 0:
answer += -heapq.heappop(steal) # 넣을 수 있는 보석 중 가장 비싼 것을 넣어줌
https://school.programmers.co.kr/learn/courses/30/lessons/142085
준호가 보유한 병사 n명 중 enemy[i]명을 소모하여 enemy[i]마리의 적을 막을 수 있다. 무적권은 최대 k번 사용할 수 있으며 병사의 소모 없이 한 라운드의 공격을 막을 수 있다.
준호는 최대 몇 라운드까지 막을 수 있을까?
for i in range(len(enemy)):
total += enemy[i] # i라운드까지 총 적의 수
if total <= n:
heapq.heappush(maxHeap, -enemy[i])
answer += 1
elif k > 0: # 적의 수가 병사의 수보다 많을 경우
k -= 1
heapq.heappush(maxHeap, -enemy[i])
total += heapq.heappop(maxHeap)
answer += 1
else:
break
각 라운드의 적의 수와 n을 비교하는 게 아니라, i 라운드까지 총 적의 수와 비교함
https://www.acmicpc.net/problem/1374
N개 강의의 시작하는 시간과 끝나는 시간을 알고 있을 때, 필요한 최소 강의실의 수?
# arr = [강의번호, 시작시간, 종료시간]
arr.sort(key=lambda x:x[1]) # 시작 시간으로 오름차순 정렬
heap = []
answer = 0
for i in arr:
while heap and heap[0] <= i[1]: # 가장 일찍 끝나는 시간보다 시작시간이 크면
heapq.heappop(heap) # 이 회의는 i번째 회의랑 동시에 진행할 수 있음
heapq.heappush(heap, i[2]) # i번째 회의의 끝나는 시간을 추가
answer = max(answer, len(heap))
중간에 강의실이 10개 필요하면 답은 10인거임
https://school.programmers.co.kr/learn/courses/30/lessons/42627
각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마나 되는지 리턴
def solution(jobs):
answer, now, i = 0, 0, 0 # now는 현재 시점
start = -1 # 바로 이전에 완료한 작업의 시작 시간
minHeap = []
while i < len(jobs):
for j in jobs:
# 현재 시점에서 처리할 수 있는 작업이라면
# 바로 이전에 완료한 작업의 시작 시간 < 작업 요청시점 <= 현재 시점
# jobs 전체를 순회하기 때문에, start가 없다면 예전에 완료한 작업도 추가될 것
if start < j[0] <= now:
heapq.heappush(minHeap, [j[1], j[0]]) # 소요시간 짧은 것부터
# 처리할 수 있는 작업이 존재하면
if len(minHeap) > 0:
cur = heapq.heappop(minHeap)
start = now
now += cur[0]
answer += (now - cur[1])
i += 1
else:
now += 1
return answer // len(jobs)