알고리즘 문제 풀이/백준

[보석 도둑/G2/Python3/C++]

제유찬 2024. 11. 18. 18:30

1202번 보석 도둑 G2

 

문제
세계적인 도둑 상덕이는 보석점을 털기로 결심했다. 상덕이가 털 보석점에는 보석이 총 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) 모든 숫자는 양의 정수이다.

출력
첫째 줄에 상덕이가 훔칠 수 있는 보석 가격의 합의 최댓값을 출력한다.



 

탐욕법으로 풀이가 가능하다.

현재 넣을 수 있는 보석 중가장 가치 있는 보석을 넣는다.

 

보석과 가방을 무게 순으로 오름차순 정렬하였다고 가정하자.

i번 가방에 보석 j를 담을 수 있었다면, i+1번 가방도 보석 j를 담을 수 있다. i+1의 담을 수 있는 무게가 i보다 큼

즉, i번에 담을 수 있는 보석은 그 후의 가방 어떤 것에도 넣을 수 있다.

 

우선순위 큐를 이용하여, 현재 넣을 수 있는 보석 중 가장 가치 있는 보석을 찾았다.

각 가방에 넣을 수 있는 보석 중 가장 가치 있는 보석을 찾으며 순회한다.

 

1. 우선순위 큐에 없는 보석 중 추가로 가방에 넣을 수 있는 보석을 모두 우선순위 큐에 넣는다.

2. 가방에 넣을 수 있는 보석 중 가장 가치 있는 보석을 넣는다.

 

최종적으로 모든 가방을 탐색하며 넣었던 가장 가치 있는 보석들의 합을 출력한다.

 

 

더보기
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    int n,k; cin>>n>>k;
    vector<pair<int, int>> jewel;
    vector<int> bags;

    priority_queue<int, vector<int>, less<int>> pq;
    
    for (int i=0; i<n; ++i)
    {
        int m,v; cin>>m>>v;
        jewel.push_back(make_pair(m, v));
    }

    for (int i=0; i<k; ++i)
    {
        int c; cin>>c;
        bags.push_back(c);
    }

    sort(jewel.begin(), jewel.end());
    sort(bags.begin(), bags.end());

    long result = 0;
    int j = 0;
    for (int i=0; i<k; ++i)
    {
        while(j<n && jewel[j].first <= bags[i])
            pq.push(jewel[j++].second);

        if(!pq.empty())
        {
            result += pq.top();
            pq.pop();
        }
    }

    cout<<result;
}



 

더보기
import heapq
import sys

jewelNum , bagNum = map(int, sys.stdin.readline().split())

jewel = []
for i in range(jewelNum):
    jewel.append(list(map(int, sys.stdin.readline().split())))

bagHeavy = []
for i in range(bagNum):
    bagHeavy.append(int(sys.stdin.readline()))

jewel.sort()
bagHeavy.sort()

heap = []
result = 0
j = 0
for i in range(bagNum):
    while j < len(jewel) and jewel[j][0] <= bagHeavy[i]:
        heapq.heappush(heap, -jewel[j][1])
        j += 1

    if len(heap) > 0:
        result -= heapq.heappop(heap)

print(result)