[C++] 백준 1202 [보석 도둑]

date:

Updated:


Categories:

Tags: , ,

접근방법

Greedy 알고리즘을 사용한다. 만약 브루트포스로 풀게 되면 시간초과가 나게된다.

풀이방법

무게가 적은 가방부터 큰 가방들까지 각 가방에 들어갈수있는 보석들 중 가치가 높은 보석을 넣으면 된다.
각 단계마다 최적의 선택을 하므로, 그리디 알고리즘이다.
1 위와 같이 무게가 적은 가방부터 채워넣는다. 단, 넣을 수 있는 보석중 가장 가치가 높은 보석을 넣는것이다.

이 그리디 알고리즘은 탐욕적 선택 속성과 최적 부분 구조를 만족하기 때문에 그 정당성을 증명할 수 있다.(정당성 증명은 추후 추가)

우선순위 큐 사용

무게 제한이 낮은 가방부터 높은 가방으로 순회하면서 그 가방이 가질 수 있는 보석들의 가치를 priority queue에 넣어준다.
이 때, 보석은 무게 순으로 오름차순 정렬되어있기 때문에, 보석 배열에 인덱스를 늘려가면서 찾아준다.
다음 가방이 가질 수 있는 보석들을 찾을 때에 보석 배열의 인덱스는 처음부터 찾는 것이 아닌, 그 다음 보석부터 찾으면 된다.
즉, 보석은 한번씩만 priority queue에 들어간다.

소스코드

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

vector<pair<int, int> > gem;
vector<int> bag;

int main(){
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    int N,K,index=0;
    long long sum = 0;
    priority_queue<int> pq;
    cin >> N >> K;
    for(int i=0; i<N; i++){
        int M,V;
        cin >> M >> V;
        gem.push_back(make_pair(M, V));
    }
    for(int i=0; i<K; i++){
        int C;
        cin >> C;
        bag.push_back(C);
    }
    sort(gem.begin(), gem.end());
    sort(bag.begin(), bag.end());
    for(int i=0; i<K; i++){
        while(gem[index].first <= bag[i] && index < N){
            pq.push(gem[index++].second);
        }
        if(!pq.empty()){
            sum += pq.top();
            pq.pop();
        }
    }
    cout << sum << "\n";
}

Leave a comment