728x90
🔗 문제 링크
2109번: 순회강연
한 저명한 학자에게 n(0 ≤ n ≤ 10,000)개의 대학에서 강연 요청을 해 왔다. 각 대학에서는 d(1 ≤ d ≤ 10,000)일 안에 와서 강연을 해 주면 p(1 ≤ p ≤ 10,000)만큼의 강연료를 지불하겠다고 알려왔다.
www.acmicpc.net
💡 문제 풀이 및 해석
일단, 보자마자 비싼 강의를 최대한 많이 들어야 한다는 것을 알 수 있다. 여기서 어떻게 들어야 할 것인가가 중요하다. 여기서 day로 정렬해서 한다면, 문제가 발생한다. 예를 들어서, 같은날 비싼 2개의 강의가 있을 때, 전날 강의를 버리고 그 다음날까지 유예기간이 있는 강의를 들을 수가 없기 때문이다. 여기서 해결방법으로는 아래와 같다.
- 가장 비싼 강의로 내림차순으로 정렬한다.
- 유예기간이 3일인 강의가 있다면, 3일에 강의일정이 있는지 확인한다.
2-1. 강의일정이 없다면, 등록한다.
2-2. 강의일정이 있다면, 그 전날에 강의일정이 있는지 확인하다. (있을 때까지 반복)
2-3. 만약, 1일까지 강의일정이 꽉차있다면 이 강의는 버린다. 그리고 앞으로 유예기간이 3일 이하는 검사할 필요가 없다. - 이렇게 모든 강의를 검사하면 벌 수 있는 최대값이 나온다.
⭐️ 정답 코드 및 설명
#include<iostream>
#include<queue>
using namespace std;
priority_queue<pair<int, int>> q;
int n;
bool visit[10001];
void input() {
cin >> n;
for (int i = 0; i < n; i++) {
int cost, day; cin >> cost >> day;
q.push({ cost,day });
}
}
int sol() {
int answer = 0;
int pass = 0;
while (!q.empty()) {
int cost = q.top().first, day = q.top().second; q.pop();
if (day < pass) continue;
for (int i = day; i > 0; i--) {
if (!visit[i]) {
visit[i] = true;
answer += cost;
break;
}
if (i == 1) pass = day;
}
}
return answer;
}
int main() {
input();
cout << sol();
return 0;
}
🤔 문제 후기
솔직히, 내가 생각한대로 풀지 못했다. 시간초과는 나지 않지만 visit을 체크하는 방법보다는 union_find 방식으로 분리집합 알고리즘을 사용해서 하면 N의 범위가 1억이 넘어가도 O(N)으로 끝낼 수 있을 것이다. 이 문제는 범위가 크지 않고, 시간도 비교적 널널 했으므로 일단, 이런 방식으로 풀어놨지만, 나중에 분리집합을 연습할 겸 다시 풀어봐야겠다.
728x90
'문제풀이 > 알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 2580 ] 스도쿠 (C++) - 백트래킹, DFS (1) | 2024.04.18 |
---|---|
[ 백준 2512 ] 예산 (C++) - 이분탐색 (0) | 2024.04.17 |
[ 백준 2565 ] 전깃줄 (C++) - DP (0) | 2024.04.15 |
[ 백준 2343 ] 기타 레슨 (C++) - 이분 탐색 (0) | 2024.04.11 |
[ 백준 15686 ] 치킨 배달 (C++) - BruteForce, 조합 (0) | 2024.04.09 |