백준 1202 보석 도둑 문제 해설을 알아보겠다. 해설은 다음 링크를 확인하면 된다. 문제 해설
1202번: 보석 도둑
첫째 줄에 N과 K가 주어진다. (1 ≤ N, K ≤ 300,000) 다음 N개 줄에는 각 보석의 정보 Mi와 Vi가 주어진다. (0 ≤ Mi, Vi ≤ 1,000,000) 다음 K개 줄에는 가방에 담을 수 있는 최대 무게 Ci가 주어진다. (1 ≤ Ci
www.acmicpc.net
해당 문제는 그리드 유형의 문제로 최적의 해를 찾기 위한 방법을 생각해야 한다. 해당 문제는 모든 경우의 수를 확인하여서 해결할 수도 있지만 최악의 경우에는 30만 X 30만 = 900억 번의 연산을 진행하여한다. 따라서 모든 경우의 수를 확인하지 않고, 버릴 수 있는 조건을 생각해야 한다. 문제 해결 과정은 다음과 같다. bags는 가방 정보, data는 보석의 가치와 무게, value는 가방에 넣을 수 있는 보석의 가치이다.
해당 문제는 가장 작은 값을 반환해주는 우선순위 큐의 성질을 사용하여 해결해야한다.
- 보석 정보를 무게를 기준으로 내림차순 정렬한다.
- 가방 정보를 내림차순 정렬한다.
- 가방 정보를 순차적으로 확인하면서 가방에 넣을 수 있는 보석의 가치를 -를 붙여서 value에 넣어준다.
- 과정 3을 반복한다.
- 더 이상 넣을 수 있는 보석이 없다면 value의 가장 앞에 있는 값을 가져와 answer에 빼준다.
위의 과정에서 보석의 가치에 -를 붙여주는 이유는 가장 작은 값을 반환하는 우선순위 큐의 성질 때문이다. -를 붙여줌으로써 가장 큰 가치를 가진 보석을 가장 작은 가치를 가진 보석으로 바꿔주고, 가장 작은 값을 반환하는 우선순위 큐가 반환하는 값이 사실은 가장 큰 가치를 가진 보석으로 되게 하기 위해서이다.
위의 과정을 코드로 작성하면 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import sys
from queue import PriorityQueue
n, k = map(int, sys.stdin.readline().split())
data, bags = [], []
value = PriorityQueue()
answer = 0
for _ in range(n):
data.append(list(map(int,sys.stdin.readline().split())))
for _ in range(k):
bags.append(int(sys.stdin.readline()))
bags.sort()
data.sort(key = lambda x : x[0])
index = 0
for i in range(k):
while index < n and bags[i] >= data[index][0]:
value.put(data[index][1] * (-1))
index += 1
if not value.empty():
answer -= value.get()
print(answer)
|
그리드 유형은 구현 난이도보다는 최적의 해를 찾는 방법을 생각하는 것이 휠씬 더 중요하다고 느끼게 해 준 문제이다.
'취업을 준비하며 정리하는 컴퓨터 지식 > Problem Solving' 카테고리의 다른 글
[Problem Solving] 백준 2225번 합분해 문제풀이 (0) | 2021.02.16 |
---|---|
[Problem Solving] 백준 2212번 센서 문제풀이 (0) | 2021.02.15 |
[ProblemSolving] 백준 10026번 적록색약 문제풀이 (0) | 2021.02.08 |
[ProblemSolving] 백준 1744번 수 묶기 문제풀이 (0) | 2021.02.05 |
[ProblemSolving] 백준 7576번 토마토 문제풀이 (0) | 2021.02.04 |