[C++] 1202: 보석 도둑

쩡우·2023년 1월 22일
0

BOJ algorithm

목록 보기
45/65

문제

세계적인 도둑 상덕이는 보석점을 털기로 결심했다.

상덕이가 털 보석점에는 보석이 총 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;
}

성공 !

profile
Jeongwoo's develop story

0개의 댓글