백준 문제풀이

백준 23750 - Leader-based Team Distribution

Vermeil 2022. 12. 12. 19:57

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

 

23750번: Leader-based Team Distribution

플레이어 $N$명이 $M$개의 팀으로 나누어 게임을 진행하려 한다. 각 팀의 인원수는 $t_1,$ $t_2,$ $\cdots,$ $t_M$이며, $i$번째 플레이어는 리더 점수 $L_i$와 플레이어 점수 $P_i$를 가진다. 각 플레이어는

www.acmicpc.net

[알고리즘 분류]

Greedy

 

 

 꽤 웰노운 그리디인 것 같다. 가장 중요한 관찰은 \(L_i\)가 가장 높은 사람이 무조건 리더가 된다는 것과, 여기에서 어떤 사람을 팀에 할당해도 리더는 변하지 않는 것이다. 그러면 이 성질을 활용하여, 계속하여 적절한 \(L_i\)를 뽑아보자.

 

 \(L_i, P_i\)에 대해 내림차순으로 정렬하자. \(1\)번째 사람은 \(1\)번째 팀의 리더가 될 수 밖에 없다. 그 후, 인덱스가 구간 \([2, T_1 + 1]\)에 속하는 사람들 중 \(P_i\)가 가장 큰 사람을 뽑는다. 이 사람은 \(2\)번째 팀의 리더가 된다. 일단 이게 왜 되는지는 직관적이게 알 수 있다.

 두번째 팀의 리더를 빨간 점들 중에서 뽑는다면, 초록색 네모칸에 해당하는 사람의 \(L_i\) 값이 더 클 때 문제가 된다. 이 사람이 리더가 되지 않는다는 것이 보장되지 않기 때문이다. 즉 구간 \([T_j + 1, T_{j+1} + 1]\)에 해당하는 사람들을 후보에 추가하고, 여기서 \(P_i\)의 값이 가장 큰 사람을 뽑으면 된다.

 

 또한 후보의 수는 많을수록 이득이므로, 배열 \(T\) 또한 내림차순으로 정렬해야 한다.

 

 후보에 사람을 추가하고, 삭제하는(리더를 뽑는) 과정은 우선순위 큐를 사용해 간단히 구현할 수 있으며, 시간복잡도는 \(O(NlogN)\)이므로 시간 안에 동작한다.

 

 발상의 과정이 이 문제와 비슷하다고 느꼈다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
 
using namespace std;
 
using ll = long long;
using ld = long double;
 
typedef pair<intint> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
 
//const ld eps = 1e-9;
const ll mod = 1e9 + 7;
const ll inf = 1e9;
 
#define all(v) v.begin(),v.end()
#define X first
#define Y second
#define endl '\n'
 
 
#define fastio ios_base::sync_with_stdio(false);cin.tie(nullptr)
 
// end of def
 
int n,m;
pii a[333333];
int t[333333];
 
 
int main() {
    fastio;
    cin>>n>>m;
    priority_queue<pii> pq;
    for (int i=0;i<n;i++)cin>>a[i].X>>a[i].Y;
    for (int i=0;i<m;i++)cin>>t[i];
    sort(a,a+n);
    reverse(a,a+n);
    sort(t,t+m);
    reverse(t,t+m);
    ll ans = 0;
    int j=1;
    pq.emplace(a[0].Y, a[0].X);
    for (int i=0;i<m;i++){
        ans += pq.top().X; pq.pop();
        for (int k=0;k<t[i];k++){
            pq.emplace(a[j+k].Y,a[j+k].X);
        }
        j+=t[i];
    }
    cout<<ans<<endl;
    return 0;
}
cs

 

'백준 문제풀이' 카테고리의 다른 글

백준 12746 - Traffic (Large)  (0) 2022.12.17
백준 1376 - 민식우선탐색  (0) 2022.12.15
2022 ICPC Seoul Regional Problem C. Empty Quadrilaterals  (5) 2022.11.21
백준 20306 - 블랙홀  (1) 2022.11.12
백준 18619 - Alakazam  (0) 2022.10.29