https://www.acmicpc.net/problem/1202
요약하자면, 첫줄에 N(보석 개수)와 K(가방 개수)가 주어지고,
다음에 N줄에 걸쳐 보석의 무게와 보석의 가격이 주어지며, 다음 K줄에 걸쳐 각 가방의 허용 무게가 주어집니다. 상덕이가 K개의 가방에 대해 각각 허용 무게를 지키며 보석을 훔칠 때, 최대 가격을 구하는 문제입니다.
여기서 한 가방에는 하나의 보석만 넣을수 있다❗️
import sys
input=sys.stdin.readline
from collections import deque
n,k =map(int, input().split())
a=[]
bag=[]
for i in range(n):
x,y=map(int, input().split())
a.append((x,y))
if k!=0:
for j in range(k):
tmp=int(input())
bag.append(tmp)
bag.sort()
a.sort(key=lambda x:x[1], reverse=True)
a=deque(a)
bag=deque(bag)
cnt=0
res=0
while bag:
temp=bag.popleft()
if cnt==k:
break
else:
for i in range(n):
if temp>= a[i][0]:
res+=a[i][1]
a.popleft()
break
cnt+=1
print(res)
else:
print(0)
힙에 대해 궁금하시다면
👉클릭
import sys
import heapq
input=sys.stdin.readline
n,k = map(int,input().split())
gem = [[*map(int,input().split())] for _ in range(n)]
bag = [int(input()) for _ in range(k)]
gem.sort();bag.sort()
result = 0;tmp = []
for bag in bag:
while gem and gem[0][0] <= bag:
heapq.heappush(tmp, -gem[0][1])
heapq.heappop(gem)
if tmp:
result -= heapq.heappop(tmp)
print(result)
총 n개의 보석, k개의 가방을 입력받습니다. gem에는 [ [ 보석무게, 보석가격], …] 형태의 2중 리스트가 생성됩니다. bag에는 k개 가방에 대해 허용 무게가 저장됩니다.
gem를 보석 무게에 대해 오름차순, 보석 무게가 같을땐 가격으로 오름차순 정렬하고, bag도 오름차순 정렬합니다. result는 k개의 가방으로 훔칠 수 있는 보석 가격의 최대값이 저장될 변수이고, 0으로 초기화 합니다. tmp는 최대 힙입니다. 가방의 무게가 작은 것부터, 해당 가방으로 훔칠 수 있는 최대 보석의 가격을 탐색하는 역할을 합니다.
for 문으로 bag에서 가방의 무게를 작은 것 부터 반복합니다. 각 가방의 무게에 대해, 그 가방으로 훔칠 수 있는 보석들을 while문을 돌며 최대 힙에 저장합니다. while 문은 gems 보석 리스트가 비어있지 않고, gems에서 제일 가벼운 보석의 무게가 bag 이하이면, tmp에 마이너스를 취해서 보석의 가격을 삽입(heappush)하고, 그 보석은 gems에서 heappop 합니다. - 를 취해서 heap에 삽입하는 이유는 보석의 무게는 0 이상인데 음수로 최소힙에 저장하면, 최소값은 음수로 제일 작은 수 이고, 이는 다시 -를 취해주면 양수로 최대값이기 때문입니다. 즉, -를 취해서 최소힙을 최대힙으로 사용하는 것 입니다.
tmp가 존재하는 경우. 즉, 현재 bag 무게 이하의 훔칠 보석이 있다면, heappop으로 최대 가격의 보석을 빼서 result에 갱신합니다. 이 때, result -= heapq.heappop(tmp)를 하는 이유는 현재 힙에 보석의 가격이 음수로 저장되있기 때문입니다.