예제 입력 1
3 2
1 65
5 23
2 99
10
2
예제 출력 1
164
- 두 가지 방법으로 풀이가 가능하다.
1) 각각의 보석을 기준으로, 보석이 어떤 가방에 들어가면 좋을까? 가격이 높은 순으로 들어갈 수 있는 가장 작은 가방에 넣고 그 가방을 지운다.
2) 각각의 가방을 기준으로, 어떤 보석이 들어가면 좋을까??
[ 풀이 1) ]
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
const int MAX_SIZE = 300000;
using namespace std;
class Jewel
{
public:
int m; // 무게
int v; // 가격
};
multiset<int> bag;
int N;
int K;
int main(void)
{
scanf("%d %d", &N, &K);
vector<Jewel> j(N);
for (int i = 0; i < N; i++)
{
scanf("%d %d", &j[i].m, &j[i].v);
}
for (int i = 0; i < K; i++)
{
int weight;
scanf("%d", &weight);
bag.insert(weight);
}
sort(j.begin(), j.end(), [](Jewel u, Jewel v) {
return u.v > v.v;
});
long long ans = 0;
for (int i = 0; i < N; i++)
{
auto it = bag.lower_bound(j[i].m); // BST 자료구조로 하면 logK에 할 수 있다. (K = 가방 개수)
if (it != bag.end())
{
ans += j[i].v;
bag.erase(it);
}
}
printf("%lld\n", ans);
return 0;
}
[ 풀이 2) ]
#include <queue>
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
class Jewel
{
public:
int m, v;
int w; // w = 1이면 가방을 의미
Jewel()
{
m = v = w = 0;
}
};
int N, K;
int main(void)
{
scanf("%d %d", &N, &K);
vector<Jewel> j(N + K);
for (int i = 0; i < N; i++)
{
scanf("%d %d", &j[i].m, &j[i].v);
}
for (int i = 0; i < K; i++)
{
scanf("%d", &j[i + N].m);
j[i + N].w = 1;
}
sort(j.begin(), j.end(), [](Jewel u, Jewel v) {
if (u.m == v.m) return u.w < v.w; // 보석이 가방보다 앞에
return u.m < v.m;
});
priority_queue<int> q;
long long ans = 0;
for (auto& p : j)
{
if (p.w == 0) // 보석이면 그 가격을 넣는다.
q.push(p.v);
else
{
if (!q.empty()) // 가방이면
{
ans += (long long)q.top(); // 현재까지 최대가격 보석
q.pop();
}
}
}
printf("%lld\n", ans);
return 0;
}
'Algorithm > 문제풀이' 카테고리의 다른 글
[그리디 알고리즘] 가장 긴 증가하는 부분 수열 2 (0) | 2019.11.07 |
---|---|
[그리디 알고리즘] 순회강연 (0) | 2019.11.07 |
[그리디 알고리즘] 동전 뒤집기 (0) | 2019.11.01 |
[그리디 알고리즘] 전구와 스위치 (2) | 2019.10.31 |
[그리디 알고리즘] 행렬 (0) | 2019.10.31 |