[백준] 1202번 보석 도둑 (C++)

2025. 12. 28. 20:49·Algorithm
728x90

https://www.acmicpc.net/problem/1202

 

 

이 문제는 N개의 보석과 K개의 배낭이 주어지며 N개의 보석은 가격과, 무게가 주어지며 K개의 배낭은 최대 무게가 주어진다.

 

이때 배낭에는 하나의 보석만 넣을 수 있고 최대 무게를 초과할 수 없다.

 

이때 배낭에 넣을 수 있는 최대 보석의 가치를 구하는 문제이다.

 

테스트케이스를 보고 보석을 순회하며 보석의 최대 무게와 배낭의 최대 무게의 차이가 크지 않는것을 찾는것이 최적이라고 생각하여

 

다음과 같이 코드를 작성하였다.

 

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    int y;
    int r;
};

struct halloween {
    int cnt;
    int score;
};

// int dx[] = {-1, 1, 0, 0, 1, -1, -1, 1};
// int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int N, K;       // 보석 개수, 가방 무게
priority_queue<pii, vector<pii>> pq;
vector<int> v;
bool visited[300001];

void solve() {
    ll answer = 0;
    sort(v.begin(), v.end());

    while(!pq.empty()) {
        int cost = pq.top().first;
        int weight = pq.top().second;
        pq.pop();

        if(K == 0) break;

        int idx = lower_bound(v.begin(), v.end(), weight) - v.begin();

        if(idx >= v.size()) {      // 발견 X
            continue;
        }
        else {
            if(visited[idx]) {
                for(int i = idx; i < v.size(); i++) {
                    if(!visited[i]) {
                        visited[i] = true;
                        K--;
                        answer += cost;
                        break;
                    }
                }
            }
            else {
                visited[idx] = true;
                K--;
                answer += cost;
            }
        }
    }

    cout << answer;
}

void input() {
    cin >> N >> K;

    for(int i = 0; i < N; i++) {
        int a, b;
        cin >> a >> b;
        pq.push({b, a});
    }

    for(int i = 0; i < K; i++) {
        int a;
        cin >> a;
        v.push_back(a);
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

하지만 시간초과를 받았고 다른 풀이를 생각해 냈어야 했다.

 

첫번째로 배낭 무게와 배낭을 정렬하여 배낭을 순회하며 배낭에 들어갈 최대 가치의 보석을 찾아야겠다고 생각이 들었다.

 

따라서 최대힙을 사용하여 보석 가치가 배낭 최대 무게보다 커질때까지 보석을 순회하였고 커질 경우 최대힙에서 하나씩 더해준다. -> 배낭에는 최대 하나의 보석만 넣을 수 있기 때문

 

 

정답코드

 

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"

const int INF = 1e9;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int N, K;
vector<pii> v;
priority_queue<int> pq;
int arr[300001];

bool compare(pii a, pii b) {
    if(a.first == b.first) {
        return a.second > b.second;
    }

    return a.first < b.first;
}

void Print() {
    for(auto it : v) {
        cout << it.first << " " << it.second << endl;
    }

    for(int i = 0; i < K; i++) {
        cout << arr[i] << " ";
    }
}

void solve() {
    sort(v.begin(), v.end(), compare);
    sort(arr, arr+K);

    int idx = 0;
    ll answer = 0;

    for(int i = 0; i < K; i++) {
        int bagsize = arr[i];

        while(idx < N) {
            int weight = v[idx].first;
            int cost = v[idx].second;

            if(weight <= bagsize) {
                pq.push(cost);
                idx++;
            }
            else break;
        }

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

    cout << answer;
}

void input() {
    cin >> N >> K;

    for(int i = 0; i < N; i++) {
        int a, b;
        cin >> a >> b;
        v.push_back({a, b});
    }

    for(int i = 0; i < K; i++) {
        cin >> arr[i];
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

728x90
저작자표시 (새창열림)

'Algorithm' 카테고리의 다른 글

[백준] 2461번 대표 선수 (C++)  (0) 2025.12.30
[백준] 1736번 쓰레기 치우기 (C++)  (0) 2025.12.29
[백준] 20366번 같이 눈사람 만들래? (C++)  (1) 2025.12.27
[백준] 14722번 우유 도시 (C++)  (0) 2025.12.26
[백준] 18513번 샘터 (C++)  (0) 2025.12.25
'Algorithm' 카테고리의 다른 글
  • [백준] 2461번 대표 선수 (C++)
  • [백준] 1736번 쓰레기 치우기 (C++)
  • [백준] 20366번 같이 눈사람 만들래? (C++)
  • [백준] 14722번 우유 도시 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (278)
      • Programming (47)
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (3)
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (1)
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (5)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    우선순위 큐
    깊이우선탐색
    WebSecurity
    투포인터
    재귀
    브루트포스
    비트마스킹
    시뮬레이션
    BFS
    정렬
    Leviathan
    DP
    누적합
    구현
    Bandit
    linux
    c언어
    DFS
    우선순위큐
    트리
    그래프 이론
    그리디
    다익스트라
    이분탐색
    백트래킹
    다이나믹 프로그래밍
    에라토스테네스의 체
    wargame
    코딩
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 1202번 보석 도둑 (C++)
상단으로

티스토리툴바