본문 바로가기

algorithm

백준 2109 순회 강연 ( greedy )

728x90

문제 : 2109번: 순회강연 (acmicpc.net)

 

2109번: 순회강연

한 저명한 학자에게 n(0 ≤ n ≤ 10,000)개의 대학에서 강연 요청을 해 왔다. 각 대학에서는 d(1 ≤ d ≤ 10,000)일 안에 와서 강연을 해 주면 p(1 ≤ p ≤ 10,000)만큼의 강연료를 지불하겠다고 알려왔다.

www.acmicpc.net

 

접근과정

이 문제를 풀기 위해서, 정렬된 vector와 priority queue 2가지를 사용했습니다.

 

처음에는 그냥 vector만을 사용해서 해당 날짜마다 가장 큰 강연료들만 더해주면 된다고 생각했는데,

문제에서 d일 안에 와서 강연을 해준다고 했지, d일에만 정확히 강연을 한다고는 하지 않았습니다.

 

예를들어 (d,p) = (1,1), (2,10), (2,10) 예제의 경우 날짜마다 가장 큰 강연료를 더해주면 11이 나오지만,

2일 안에 10짜리 강연료 2개를 할 수도 있기 때문에 답은 20이 나와야 합니다.

 

풀이과정

1. vector에 d,p 값들을 넣고 정렬을 해주는데

먼저 d에 대해 오름차순 정렬을 하고 d값이 같다면 p에 대해 오름차순이 되어야 합니다.

 

2. priority_queue 또한 오름차순 정렬이 되도록 생성합니다.

for문을 순회하면서 강연료를 하나씩 넣어주고 answer에도 누적해서 더해주는데,

만약 pq의 크기가 앞서 더했던 강연료의 기간보다 더 크다면, pq의 첫번째 값만큼을 빼주도록 합니다.

 

(d,p) = (1,1), (2,10), (2,10) 이 예제를 다시 살펴보면,

1. 첫 번째, 두 번째 값까지는 pq에 넣어주게 되고, 

2. 세 번째 값인 10을 넣었을 경우 해당 d 값보다 pq의 크기가 더 크기 때문에

pq의 top ( 가장 작은 값 ) 만큼을 빼주게 되며 답이 구해지게 됩니다.

 

 

#include <iostream>
#include <vector>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
int N;
int p,d;
typedef struct option {
    int range, money;
}op;
vector < op > v;
priority_queue < int , vector < int >, greater < int > > pq;

bool cmp(const op &a, const op &b) {
    if(a.range < b.range) return true;
    else if(a.range == b.range) {
        if(a.money < b.money) return true;
    }
    return false;
}

int solution() {
    int ans = 0;
    for(int i=0; i<N; i++) {
        pq.push(v[i].money);
        ans += v[i].money;

        if(pq.size() > v[i].range) {
            ans -= pq.top();
            pq.pop();
        }
    }
    return ans;
}

int main()
{
    scanf("%d",&N);
    for(int i=0; i<N; i++) {
        scanf("%d %d",&p,&d);
        v.push_back({d,p});
    }
    sort(v.begin(),v.end(),cmp);
    printf("%d\n",solution());
}
728x90

'algorithm' 카테고리의 다른 글

백준 14500 - 테트로미노  (0) 2021.09.30
백준 17298 오큰수 (stack)  (0) 2021.09.26
백준 2457-공주님의 정원 (greedy)  (0) 2021.09.05
백준 12904 - A와 B (greedy)  (0) 2021.09.04
백준 10775 공항 (union-find algorithm)  (0) 2021.08.25