Algorithm/Greedy Algorithm

[백준 1202번] 보석 도둑(Java 풀이)

agility 2022. 2. 28. 16:47

백준알고리즘 1202번 : 보석 도둑

 

 

 

시간 초과와 RunTime Error를 반복한 끝에 성공했다.

우선순위큐(Priority Queue)의 중요성을 배운 문제이다.

이중for문(혹은 for문과 while문)을 사용하게 된다면 최대 30만*30만의 시간복잡도가 발생하게된다.

따라서 가방의 최대 무게외 보석의 정보 배열을 정렬했다고 하더라도

시간 제한이 걸리는 testCase가 발생하기 때문에.. 이 방식은 한 번 해보고 빠르게 접었다.

우선순위큐의 장점은, 내가 add한 Queue 중 최대값(혹은 최소값)을 poll할 수 있다는 점이다.

이는 인자들을 꾸준히 더하거나 빼야하는 상황이나
(특정 가방이 들수 있는 보석들을 모두 담고, 하나의 보석만 빼고 남겨둬야한다.)

인자들의 최대, 최소값을 구해야하는 상황에서
(담긴 보석들 중 가장 비싼 보석만 pick한다.)

ArrayList나 Stack, Queue, 배열 등을 사용하는 것보다 낮은 시간복잡도를 기대할 수 있다.

 

 

풀이 과정


1. 보석을 2차원 배열에 담고, 무게의 오름차순으로 정렬한다.
2. 가방의 최대 무게 배열도 오름차순으로 정렬한다.
3. 우선순위큐를 내림차순으로 정의한다.
4. 가방 배열만큼 for문을 돌려, 가방이 담을수 있는 최대 무게보다 덜 나가는 보석들은 모두
   우선순위큐에 담은 뒤, 우선순위큐의 최상위 값을 poll하고 다음 가방 배열로 넘어간다.
4-1. 가방이 담을 수 있는 보석이 없을 수도있으니, 적절한 예외처리를 해준다.
5. poll된 값들을 더하여 출력한다.

 

 

 

소스 ▽

더보기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {// No1202 보석 도둑
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = Integer.parseInt(st.nextToken());// 보석의 갯수
		int K = Integer.parseInt(st.nextToken());// 가방의 갯수
		PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
		Integer[] bags = new Integer[K];
		Integer[][] jewelry = new Integer[N][2];

		for (int i = 0; i < N; i++) {
			StringTokenizer st1 = new StringTokenizer(br.readLine());
			jewelry[i][0] = Integer.parseInt(st1.nextToken());
			jewelry[i][1] = Integer.parseInt(st1.nextToken());
		}

		for (int i = 0; i < K; i++) {
			bags[i] = Integer.parseInt(br.readLine());
		}

		Arrays.sort(jewelry, new Comparator<Integer[]>() {

			@Override
			public int compare(Integer[] o1, Integer[] o2) {
				return o1[0] - o2[0];
			}
		});

		Arrays.sort(bags);
		long ans = 0;

		int cnt = 0;
		for (int i = 0; i < bags.length; i++) {
			while (cnt < N && bags[i] >= jewelry[cnt][0]) {
				pq.add(jewelry[cnt][1]);
				cnt++;
			}

			if (!pq.isEmpty()) {
				ans += pq.poll();
			}
		}

		System.out.println(ans);

	}

}