세계적인 도둑 상덕이는 보석점을 털기로 결심했다.
상덕이가 털 보석점에는 보석이 총 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)
모든 숫자는 양의 정수이다.
첫째 줄에 상덕이가 훔칠 수 있는 보석 가격의 합의 최댓값을 출력한다.
우선순위 큐 문제!
보석은 무게 순으로 오름차순 정렬, 가방은 용량 순으로 오름차순 정렬한다.
모든 가방의 용량을 확인하면서, 각 가방마다 넣을 수 있는 모든 보석을 우선순위 큐에 넣는다. 우선순위 큐의 우선순위는 보석의 가격이 높을수록 높다. 보석이 무게 순으로 오름차순 정렬되어있기 때문에, 보석 array의 index를 ++하면서 한 번 큐에 넣은 보석은 다시 넣지 않는다.
해당 가방에 담을 수 있는 모든 보석을 우선순위 큐에 넣은 후에, 우선순위 큐의 앞에서 보석 하나를 꺼내 가방에 담는다. 해당 보석은 가방에 담을 수 있는 보석 중 가격이 가장 높은 보석이다. 이 과정을 모든 가방에 반복한다.
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
void input_data(void);
void find_max(void);
struct cmp {
bool operator()(pair<int, int>&a, pair<int, int>&b) {
return (a.second < b.second);
}
};
int n, m, v, k, c;
long long result;
int bag[300000];
pair<int, int> gem[300000];
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> gem_q;
int main(void)
{
input_data();
find_max();
return (0);
}
void input_data(void)
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
int i = -1;
while (++i < n)
cin >> gem[i].first >> gem[i].second;
i = -1;
while (++i < k)
cin >> bag[i];
sort(gem, gem + n);
sort(bag, bag + k);
return ;
}
void find_max(void)
{
int bag_idx = -1, gem_idx = 0;
while (++bag_idx < k)
{
while (bag[bag_idx] >= gem[gem_idx].first && gem_idx < n)
{
gem_q.push(gem[gem_idx]);
gem_idx++;
}
if (!gem_q.empty())
{
result += gem_q.top().second;
gem_q.pop();
}
}
cout << result << '\n';
return;
}
성공 !