메모리: 107892 KB, 시간: 1396 ms
자료 구조, 그리디 알고리즘, 정렬, 우선순위 큐
세계적인 도둑 상덕이는 보석점을 털기로 결심했다.
상덕이가 털 보석점에는 보석이 총 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)
모든 숫자는 양의 정수이다.
첫째 줄에 상덕이가 훔칠 수 있는 보석 가격의 합의 최댓값을 출력한다.
이 문제는 보석의 무게와 가격, 그리고 가방의 최대 무게 제한이 주어졌을 때, 가방에 담을 수 있는 보석 가격의 합의 최댓값을 구하는 문제입니다. 각 가방에는 하나의 보석만 담을 수 있습니다.
이 문제는 그리디 알고리즘과 우선순위 큐(heapq)를 사용하여 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.
n, k = map(int, input().split()): 보석의 개수 N과 가방의 개수 K를 입력받습니다.jewels = []: 보석 정보를 저장할 리스트를 초기화합니다.bags = []: 가방 정보를 저장할 리스트를 초기화합니다.for i in range(n): jewels.append(list(map(int, input().split()))): 보석의 무게와 가격을 입력받아 jewels 리스트에 저장합니다.for i in range(k): bags.append(int(input())): 가방의 최대 무게를 입력받아 bags 리스트에 저장합니다.jewels.sort(reverse=True): 보석을 가격이 높은 순서대로 정렬합니다. (무게가 작은 순서로 정렬하고 가방에 담을 수 있는지 확인하는 방식도 가능)bags.sort(): 가방을 무게 제한이 작은 순서대로 정렬합니다.can_take = []: 현재 가방에 넣을 수 있는 보석들의 가격을 저장하는 최소 힙(min heap)입니다. (파이썬의 heapq는 최소 힙을 제공하므로, 가격에 음수를 취해 최대 힙처럼 사용합니다.)answer = 0: 훔칠 수 있는 보석 가격의 합을 저장할 변수를 초기화합니다.for bag in bags:: 각 가방에 대해 반복합니다.while jewels:: 아직 확인하지 않은 보석이 있는 동안 반복합니다.if jewels[-1][0] <= bag:: 현재 보석의 무게가 가방의 최대 무게보다 작거나 같으면 (가방에 넣을 수 있으면)weight, value = jewels.pop(): 보석 리스트에서 해당 보석을 꺼내고 무게와 가격을 저장합니다.heapq.heappush(can_take, -value): 보석의 가격에 음수를 취하여 can_take 힙에 넣습니다.else: break: 현재 보석의 무게가 가방의 최대 무게보다 크면, 더 이상 현재 가방에 넣을 수 있는 보석이 없으므로 내부 while 루프를 종료합니다.if can_take:: 현재 가방에 넣을 수 있는 보석이 하나 이상 있다면,answer -= heapq.heappop(can_take): can_take 힙에서 가장 작은 값(절댓값이 가장 큰 음수, 즉 가장 비싼 보석)을 꺼내어 answer에 더합니다.print(answer): 훔칠 수 있는 보석 가격의 합의 최댓값을 출력합니다.시간 복잡도:
공간 복잡도:
jewels: O(N)bags: O(K)can_take: O(N) (최악의 경우 모든 보석이 힙에 들어갈 수 있음)import sys
import heapq
input = sys.stdin.readline
n,k = map(int, input().split())
jewels = []
for i in range(n):
jewels.append(list(map(int, input().split())))
bags= []
for i in range(k):
bags.append(int(input()))
jewels.sort(reverse=True)
bags.sort()
can_take = []
answer = 0
for bag in bags:
while jewels:
if jewels[-1][0] <= bag:
weight, value = jewels.pop()
heapq.heappush(can_take, -value)
else:
break
if can_take:
answer -= heapq.heappop(can_take)
print(answer)