본문으로 바로가기

[우선순위 큐] 순회 강연 2109

category ps/그리디 알고리즘 2021. 10. 31. 14:17

문제 해설 및 주의사항

한 저명한 학자에게 n(0 ≤ n ≤ 10,000)개의 대학에서 강연 요청을 해 왔다. 각 대학에서는 d(1 ≤ d ≤ 10,000)일 안에 와서 강연을 해 주면 p(1 ≤ p ≤ 10,000)만큼의 강연료를 지불하겠다고 알려왔다. 각 대학에서 제시하는 d와 p값은 서로 다를 수도 있다. 이 학자는 이를 바탕으로, 가장 많은 돈을 벌 수 있도록 순회강연을 하려 한다. 강연의 특성상, 이 학자는 하루에 최대 한 곳에서만 강연을 할 수 있다.

예를 들어 네 대학에서 제시한 p값이 각각 50, 10, 20, 30이고, d값이 차례로 2, 1, 2, 1 이라고 하자. 이럴 때에는 첫째 날에 4번 대학에서 강연을 하고, 둘째 날에 1번 대학에서 강연을 하면 80만큼의 돈을 벌 수 있다.

 

 

풀이

1. 그리디 알고리즘

- 현재 날짜에서, 가능한 높은 pay 가 높은 강의를 고른다.

 

2. 우선순위 큐를 활용한 구현

2-0. 받은 강의의 값들을 날짜 기준 내림차순으로 정렬한다.

2-1. 10,000 일부터 1일까지 아래와 같이 순회한다.

2-2. i 는 10,000 부터 1까지 날짜를 순회한다. index 는 lectures 를 0 부터 n - 1까지 순회한다.

이때, i 와 day 가 일치하는 lectures 의 pay 를 모두 우선순위 큐에 넣어준다.

그 후, 우선순위 큐의 top 을 답에 더해준다.

풀이코드

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
// 2109 순회 강연

struct Lecture{
	int pay, day;
};

// 날짜 내림차순 정렬
bool cmp(const Lecture &u, Lecture &v){
	return u.day > v.day;
}

int main(){
	int n;
	 cin >> n;
	vector<Lecture> lectures(n);
	
	for(int i=0; i <n; i++){
		cin >> lectures[i].pay >> lectures[i].day;
	}
	
	sort(lectures.begin(), lectures.end(), cmp);
	
	int index = 0;
	priority_queue<int> q;
	int ans = 0;
	
	for(int i = 10000; i >=1 ; i--){
		// i 일까지 할 수 있는 강의를 후보로 넣어주는 부분
		// 우선순위 큐에 넣었으므로, i 일까지 할 수 있는 강의들 중 top 이 최고 pay 를 주는 강의이다		
		while(index < n && lectures[index].day == i){
			q.push(lectures[index].pay);
			index += 1;
		}
		
		// i 일에 어떤 강연을 할지 결정하는 부분
		// 우선순위 큐가 비지 않았다면, 최대값을 더한다.
		if(!q.empty()){
			ans += q.top();
			q.pop();
		}
	}
	cout << ans << endl;
}

 


퇴고

1. 문제를 잘 읽자.

- 처음 문제를 읽었을 때, 해당 일에만 해당 강연을 할 수 있는줄 알고 시간 낭비를 했었다.

반응형

'ps > 그리디 알고리즘' 카테고리의 다른 글

잃어버린 괄호 1541  (0) 2021.10.31
가장 긴 증가하는 부분 수열 2 (LIS)  (0) 2021.10.31
[priority queue] [multiset] 보석 도둑 1202  (0) 2021.10.28
행렬 1080  (0) 2021.10.25
회의실 배정 1931  (0) 2021.10.25