알고리즘
백준 g2 1202 보석 도둑 c++
kyj0032
2024. 3. 8. 14:08
https://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가 주어진다.
각 가방에는 보석을 1개만 담을 수 있다.
상덕이가 훔칠 수 있는 보석 가격 합의 최대는?
풀이(https://blog.encrypted.gg/1013)
그리디로 풀 수 있는 풀이
각 가방에는 보석을 하나만 담을 수 있다는 시점에서 최대 가격의 보석을 최대한 작은 무게의 가방에 넣는 것이 이득이라고 생각할 수 있다. 자세한 풀이는 위 링크 참고 .. 수학적 접근은 아직 나한텐 너무 어려움
수도 코드
보석 내림차순 정렬, 가방 오름차순 정렬
for 가장 가격이 큰 보석부터
w = 그 보석의 무게
가방 it = lower_bound(w)
if w == set.end() // 값이 없으면
continue
else
해당 가방 it 삭제 <-- //lower_bound를 계속 쓰려면 쓴 가방을 삭제해야 하므로
//빈번한 삭제가 일어나는데 유리한 set사용
answer += 보석 가치
사용한 가방은 삭제해야하므로, 삭제가 빠른 시간 안에 일어나고 lower_bound도 쓸 수 있는 set이 적합하다.
전체 코드
/*boj g2 1202 보석 도둑*/
#include <algorithm>
#include <iostream>
#include <set>
#define MAXN 300005
using namespace std;
int N, K;
pair<int, int> jewel[MAXN]; // 가격, 무게
multiset<int> bag;
long long answer;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
// 0. input
cin >> N >> K;
for (int i = 0; i < N; i++) {
int m, v;
cin >> m >> v;
jewel[i] = make_pair(v, m);
}
for (int i = 0; i < K; i++) {
int c;
cin >> c;
bag.insert(c);
}
// 1. 정렬
sort(jewel, jewel + N, greater<>());
// 2. 가장 큰 보석부터 가능한 제일 작은 가방에 넣기
for (int i = 0; i < N; i++) {
int weight = jewel[i].second;
auto it = bag.lower_bound(weight);
if (it == bag.end()) { // 만족하는 가방이 없음
continue;
} else {
bag.erase(it);
answer += jewel[i].first;
}
}
cout << answer << "\n";
}