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
이 문제는 보석을 전부 우선순위 큐에 넣어주고, 이분탐색으로 해당 보석을 넣을 수 있는 가방 중 가장 작은 것을 고르는 식으로, 우선순위큐 + 이분탐색으로 풀려고 했다가 시간초과로 실패하고 아래 블로그를 보고 공부했다.
https://jaimemin.tistory.com/760
백준 1202번 보석 도둑
문제 링크입니다: https://www.acmicpc.net/problem/1202 그리디(Greedy) 알고리즘에 우선순위 큐(Priority Queue) 자료구조를 사용해야 했던 문제였습니다. 우선순위 큐 자료구조를 사용하는 부분은 종신1재정2.
jaimemin.tistory.com
풀이
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
using pii = pair<int, int>;
int bag[300'000];
pii jw[300'000];
priority_queue<int> pq;
void solution() {
int n, k, idx;
long long sum = 0;
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> jw[i].first >> jw[i].second;
}
for (int i = 0; i < k; i++) {
cin >> bag[i];
}
sort(jw, jw + n);
sort(bag, bag + k);
idx = 0;
for (int i = 0; i < k; i++) {
//현재 가방이 수용할 수 있는 무게보다 작거나 같은
//보석들을 전부 우선순위큐에 넣어준다.
while (idx < n && jw[idx].first <= bag[i]) {
pq.push(jw[idx].second);
++idx;
}
//현재 우선순위큐에는 현재 가방에 들어갈 수 있는 보석들이
//maxheap형태로 저장되어있으므로, 가장 value가 높은 보석을 가방에 담는다.
if (!pq.empty()) {
sum += pq.top();
pq.pop();
}
}
cout << sum << '\n';
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
solution();
return 0;
}
메모리: 7204 kb | 시간: 160 ms |
보석이 아닌 가방을 기준으로 현재 가방에 들어올 수 있는 보석들을 우선순위 큐에 넣어 가장 큰 값을 고르는 식으로 문제를 해결함으로써 O(K + NlogN)의 시간복잡도로 해결 가능하다. (단, 1 <= N, K <= 300000)
반면 내가 처음 시도한 풀이는 아래의 코드인데, 사용한 가방을 처리하는 과정이 O(K)의 시간복잡도를 가지므로 최대 O(NK)의 시간복잡도를 가지므로 시간초과가 발생한다.
//************************ 틀린코드: 시간 초과 ****************************************
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#define BOUND bag.begin(),bag.end()
using namespace std;
using pii = pair<int, int>;
vector<int> bag;
priority_queue<pii> pq;
void solution() {
int n, k, m, v;
long long sum = 0;
cin >> n >> k;
while (n--) {
cin >> m >> v;
pq.emplace(v, -m);
}
for (int i = 0; i < k; i++) {
cin >> m;
bag.push_back(m);
}
sort(BOUND);
//pq는 value를 기준으로 내림차순, value가 같다면 무게를 기준으로 오름차순
while (!pq.empty() && !bag.empty()) {
v = pq.top().first, m = -pq.top().second;
pq.pop();
auto it = lower_bound(BOUND, m);
//담을 수 있는 가방이 없는 경우
if (it == bag.end()) continue;
sum += v;
bag.erase(it);
}
cout << sum << '\n';
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
solution();
return 0;
}
'컴퓨터 사이언스 > 1고리즘' 카테고리의 다른 글
백준 10775 : 공항 (0) | 2021.08.06 |
---|---|
백준 1701 : Cubeditor (0) | 2021.08.05 |
백준 4828 : XML (0) | 2021.08.03 |
백준 16458 : 가장 큰 숫자 (0) | 2021.08.03 |
백준 4358 : 생태학 (0) | 2021.08.02 |