*[백준][1202] 보석 도둑
www.acmicpc.net/problem/1202
1202번: 보석 도둑
첫째 줄에 N과 K가 주어진다. (1 ≤ N, K ≤ 300,000) 다음 N개 줄에는 각 보석의 정보 Mi와 Vi가 주어진다. (0 ≤ Mi, Vi ≤ 1,000,000) 다음 K개 줄에는 가방에 담을 수 있는 최대 무게 Ci가 주어진다. (1 ≤ Ci
www.acmicpc.net
문제
세계적인 도둑 상덕이는 보석점을 털기로 결심했다.
상덕이가 털 보석점에는 보석이 총 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)
모든 숫자는 양의 정수이다.
출력
첫째 줄에 상덕이가 훔칠 수 있는 보석 가격의 합의 최댓값을 출력한다.
해결방법
1. 입력 받은 보석의 정보(무게, 가격) 중 무게를 기준으로 오름차순 정렬을 하였다.
2. 가방의 무게도 오름차순으로 정렬을 하였다.
3. 현재 가방의 무게에 담을 수 있는 보석들을 모두 priority_queue에 담았다. pq의 root에는 젤 비싼 보석이 위치하게 된다. 또 한 다음 가방의 최고 가격의 보석을 찾을 때도 이전에 담아둔 pq에 누적되어 root값을 취하면 된다.
이 말은 다음 가방의 무게가 더 많이 담을 수 있으므로, 이전에 가방에서 채운 보석은 다시 찾기 않아도 되는 것이다.
4. 이러한 순서대로 가방 갯수 만큼 최고 가격의 보석을 채워 넣어 해결하였다.
소스코드
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
typedef unsigned long long ull;
bool cmp(pair<int, int> p1, pair<int, int> p2) {
//보석 무게 오름차순
return p1.first < p2.first;
}
int main()
{
int N, K; //N = 보석 수, K = 가방 수
ull answer = 0;
vector<pair<int, int>> jewelry;
vector<int> bags;
priority_queue<int> pq;
scanf("%d %d", &N, &K);
for (int i = 0; i < N; i++) {
int m, v;
scanf("%d %d", &m, &v);
jewelry.push_back(make_pair(m, v));
}
for (int i = 0; i < K; i++) {
int n;
scanf("%d", &n);
bags.push_back(n);
}
sort(jewelry.begin(), jewelry.end(), cmp); //보석 무게 오름차순
sort(bags.begin(), bags.end()); //가방 무게 오름차순
int jewelryIndex = 0;
for (int i = 0; i < K; i++) {
int w = bags[i];
while (jewelryIndex < N && w >= jewelry[jewelryIndex].first) {
pq.push(jewelry[jewelryIndex].second);// 보석의 무게만 담음
jewelryIndex++;
}
if (!pq.empty()) {
answer += pq.top(); pq.pop();
}
}
printf("%llu\n", answer);
}
결과