[ baekjoon ] 1202. 보석도둑

애이용·2021년 2월 10일
0

BOJ

목록 보기
32/58
post-thumbnail
post-custom-banner

1202. 보석도둑

문제

세계적인 도둑 상덕이는 보석점을 털기로 결심했다.

상덕이가 털 보석점에는 보석이 총 N개 있다. 각 보석은 무게 Mi와 가격 Vi를 가지고 있다. 상덕이는 가방을 K개 가지고 있고, 각 가방에 담을 수 있는 최대 무게는 Ci이다. 가방에는 최대 한 개의 보석만 넣을 수 있다.

상덕이가 훔칠 수 있는 보석의 최대 가격을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N과 K가 주어진다. (1 ≤ N, K ≤ 300,000)

다음 N개 줄에는 각 보석의 정보 Mi와 Vi가 주어진다. (0 ≤ Mi, Vi ≤ 1,000,000)

다음 K개 줄에는 가방에 담을 수 있는 최대 무게 Ci가 주어진다. (1 ≤ Ci ≤ 100,000,000)

모든 숫자는 양의 정수이다.

출력

첫째 줄에 상덕이가 훔칠 수 있는 보석 가격의 합의 최댓값을 출력한다.

## 1202. 보석 도둑
import sys
import heapq
input = sys.stdin.readline

# 보석의 개수, 가방의 개수
n, k = map(int, input().split())

info = [] # 보석의 정보(무게, 가격)
for _ in range(n):
  info.append(list(map(int, input().split())))

max_weight = []
for _ in range(k):
  max_weight.append(int(input())) # 가방에 담을 수 있는 최대 무게 c

# 상덕이가 훔칠 수 있는 보석의 최대 가격 구하라
info.sort()
max_weight.sort()

heap = [] # 최대힙 만들자
result = 0

# 가방 개수만큼 반복하자
jew = 0
for weight in max_weight:
  while jew < n:
    if weight >= info[jew][0]:
      heapq.heappush(heap, (-1) * info[jew][1]) # 최대힙 만들기 위해 -1 곱함
      jew += 1
    else:
      break
        
  if heap:
    result += (-1) * heapq.heappop(heap)

print(result)

처음엔 heapq를 써야하나? 생각했지만 나는 info, max_weight를 내림차순으로 정렬하려고 했기 때문에,
기본 최소힙을 쓰는 heapq말고 deque를 이용해 pop을 하려고 했다(max_weight) 하지만 7%에서 계속 실패했다
그래서 계속 하다가 안돼서 찾아보니 heapq 최대힙으로 구성해서 문제를 푸는 것이었다
우선순위큐 라이브러리는 따로 있는 것 같았지만 일단 아는 heapq를 이용했다.

처음에 반복문을

  while weight >= info[jew][0]: # 가방 무게가 더 클때까지만 heappush 하자
    heapq.heappush(heap, (-1) * info[jew][1])
    if jew == n - 1: break
    jew += 1
    if heap:
      result += (-1) * heapq.heappop(heap)

위의 코드로 작성했는데 7%에서 실패했다.
가방의 개수를 기준으로 먼저 for문을 돌려야 한다. 가방 K개를 다 반복하면 종료한다. 그 후 while문에서 보석을 모두 검사하면 종료되게끔 조건을 작성한다.

이 문제를 풀면서 heapq에 대해 더 정리해봐야 할 듯하다! 기본 최소힙으로 구성됐지만 최대힙으로 할 수 있는 거 정리해놔야지!

profile
로그를 남기자 〰️
post-custom-banner

0개의 댓글