Pepperminttt
Pepperminttt's Dev
Pepperminttt
전체 방문자
오늘
어제
  • devInfo (86)
    • forBeingGoodDeveloper (2)
    • React (2)
      • LostArk Open API (1)
    • algorithm (58)
      • problems (44)
      • theory (14)
    • computerScience (8)
      • network (8)
    • javaScript (8)
    • Java (4)
    • web (2)
      • webApplication (2)
    • etc. (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • dfs
  • 프로그래머스
  • greedy
  • DP문제
  • 탐욕법 문제
  • JavaScript
  • 알고리즘
  • 백준
  • DP
  • Network
  • 그래프
  • Java
  • 탐욕법
  • dfs문제
  • 벨만-포드
  • C++
  • bfs문제
  • node.js
  • solved.ac
  • BFS

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Pepperminttt

Pepperminttt's Dev

[백준 / Java] 1202번 : 보석 도둑
algorithm/problems

[백준 / Java] 1202번 : 보석 도둑

2023. 8. 12. 10:10

문제

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

상덕이가 털 보석점에는 보석이 총 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)

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

출력

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

예제 입력 1 복사

2 1
5 10
100 100
11

예제 출력 1 복사

10

예제 입력 2 복사

3 2
1 65
5 23
2 99
10
2

예제 출력 2 복사

164

https://www.acmicpc.net/problem/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


문제 풀이

 해당 문제는 간단한 그리디 문제로 보이지만 일차원적으로 그리디로만 푼다면 쉽게 풀 수 있지만, 시간복잡도에서 통과하기가 쉽지 않은 문제였다.

 처음에 풀 때, 우선 순위 큐를 사용하여 해당 무게에서 최대로 챙길 수 있는 무게를 구했지만 시간 초과가 떴다.

 

 이 후 추가적으로 tempPq를 생성하여 최적의 보석을 제거하고 다시 pq에 넣어가며 두개의  우선 순위 큐를 사용해보았지만 이 방법으로도 시간 초과가 떴다.

 

이 문제에서 효율적으로 그리디를 진행하기 위해서는 리스트와 우선순위 큐를 같이 사용하는 것이다.

 

문제 풀이 과정은 아래와 같다.

  1. 보석을 arraylist로 입력받은 후 무게 순서대로 오름차순 정렬한다.
  2. 가방에 담을 수 있는 최대 무게를 입력 받은 후 오름차순 정렬한다.
  3. 가격 순서대로 내림차순 정렬을 하는 우선순위 큐를 생성한다.
  4. 현재 가방이 담을 수 있는 최대 무게보다 작거나 같은 무게를 가진 보석을 우선순위 큐에 담아준다.
  5. 우선순위 큐의 제일 첫 번째 값(가장 가격이 비싼 보석)을 꺼내어 더해준다.
  6. 4 ~ 5를 반복해주면 된다.

처음에 풀 때는 Class에 compareTo 메서드를 설정하여 하나의 기준으로 정렬을 하였지만 위 과정에서는 리스트와 우선 순위 큐의 조건을 다르게 설정하여서 풀었다.

  • 리스트 : 무게 오름차순
  • 우선 순위 큐 : 가격 내림차순

위와 같이 적용을 하여 현재 가방에서 가지고 갈 수 있는 보석 중 peek의 가장 가격이 높은 보석을 챙기는 방식으로 구현하였다.


 

풀이 코드

import java.util.*;
import java.io.*;

public class Main {
	public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	public static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	public static StringTokenizer st;
	public static int INF = 100_000_000;
	public static int[] dx = {0,1,0,-1};
	public static int[] dy = {-1,0,1,0};


	public static class Crystal{
		int mass;
		int value;
		
		public Crystal() {}
		public Crystal(int mass, int value) {
			this.mass = mass;
			this.value = value;
		}
		@Override
		public String toString() {
			return "Crystal [mass=" + mass + ", value=" + value + "]";
		}
	}
	
	public static void main(String[] args) throws IOException{
		st = new StringTokenizer(br.readLine());
		
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		
		List<Crystal> list = new ArrayList<>();
		int[] backpack = new int[M];
		
		for(int i = 0 ; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			
			int m = Integer.parseInt(st.nextToken());
			int v = Integer.parseInt(st.nextToken());
			
			list.add(new Crystal(m,v));
		}
		
		Collections.sort(list,(a,b) -> a.mass - b.mass);
		
		for(int i = 0; i < M; i++) {
			int size = Integer.parseInt(br.readLine());
			backpack[i] = size;
		}
		
	    Arrays.sort(backpack);

	    int listIdx = 0;
	    long answer = 0;
	    
	    PriorityQueue<Crystal> pq = new PriorityQueue<>((a,b) -> b.value - a.value); 
	    
	    for(int i = 0 ; i < M; i++) { 
	    	while(listIdx < N && list.get(listIdx).mass <= backpack[i]) {
	    		Crystal cur =list.get(listIdx++);
	    		pq.add(new Crystal(cur.mass,cur.value));
	    	}
	    	if(!pq.isEmpty()) answer+=pq.poll().value;
	    }
		System.out.println(answer);
	}
}

 

'algorithm > problems' 카테고리의 다른 글

[백준 / Java] 1647번 : 도시 분할 계획  (0) 2023.08.17
[백준 / Java] 1644번 : 소수의 연속합  (0) 2023.08.16
[백준 / Java] 1197번 : 최소 스패닝 트리  (0) 2023.08.11
[백준 / Java] 17144번 : 미세먼지 안녕!  (0) 2023.08.08
[백준 / Java] 11053번 : 가장 긴 증가하는 부분 수열  (0) 2023.08.04
    'algorithm/problems' 카테고리의 다른 글
    • [백준 / Java] 1647번 : 도시 분할 계획
    • [백준 / Java] 1644번 : 소수의 연속합
    • [백준 / Java] 1197번 : 최소 스패닝 트리
    • [백준 / Java] 17144번 : 미세먼지 안녕!
    Pepperminttt
    Pepperminttt
    HTML, JavaScript, Python 등 Computer language TIL

    티스토리툴바