article thumbnail image
Published 2021. 11. 24. 13:11

문제 설명

문제 링크

http://icpc.me/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

풀이

그리디로 풀 수 있다.

보석의 정보를 보석의 가격을 기준으로 내림차순으로 정렬한다.

그 후에 처음부터 가격이 높은 것부터 차례대로 무게보다는 크거나 같은 최소 가방을 찾으며 가방을 매칭 시켜주면 된다. 

가방을 매칭시켜줄때는 lower_bound를 이용하면 된다.

또한 가방을 매칭시키고 바로 없애주기 위해 multiset 자료구조를 사용한다.

cf) 모든 보석을 담을 수 있다면 최대 3*10^5 * 10^6으로 int형 범위를 넘어간다.

코드

#include <cstdio>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;

pair<int, int> arr[300005];
multiset<int> m;

int main() {
    int n, k; scanf("%d %d", &n, &k);
    for (int i = 0; i < n; i++) scanf("%d %d", &arr[i].first, &arr[i].second);
    for (int i = 0; i < k; i++) {
        int k; scanf("%d", &k);
        m.insert(k);
    }
    sort(arr, arr + n, [](const auto &a, const auto &b) { 
        if (a.second == b.second) return a.first < b.first;
        return a.second > b.second; 
    });
    ll ans = 0;
    for (int i = 0; i < n; i++) if (!m.empty()) {
        auto [f, s] = arr[i];
        auto iter = m.lower_bound(f);
        if (iter != m.end()) {
            ans += s;
            m.extract(*iter);
        }
    }
    printf("%lld", ans);
}

'Algorithm > BOJ' 카테고리의 다른 글

백준[1208] 부분수열의 합 2  (0) 2022.01.09
백준[6086] 최대 유량  (0) 2021.12.27
백준[5719] 거의 최단 경로  (0) 2021.11.23
백준[15678] 연세워터파크  (0) 2021.11.23
백준[1671] 상어의 저녁식사  (0) 2021.11.18
복사했습니다!