학생 명이 미술 대회에 참가하였다. 이 대회에서는 주최자 한 명과 심판 한 명이 수상자를 결정하며, 수상자 결정 방식은 다음과 같다.
주최자와 심판이 각자 모든 학생들의 작품에 점수를 매긴다. 두 사람 모두 점수를 매길 때 서로 다른 두 작품에 같은 점수를 주지 않는다.
주최자가 명의 학생을 골라 특별상을 수여한다.
심판은 특별상을 받지 않은 학생들이 그린 작품 중 자신이 매긴 점수가 가장 높은 개의 작품을 추리고, 그에 해당하는 명의 학생에게 본상을 수여한다.
주최자는 대회에서 종류와 상관 없이 상을 받는 학생들의 작품에 대해 자신이 매긴 점수의 합이 최대가 되도록 하려고 한다. 가능한 합의 최댓값을 구하여라.
N <= 200000의 제한
M 명의 학생을 고른다.(특별상 수여)
점수는 10의 9승
특별상 제외 심판이 준 K등 까지 (본 상 수여)
N이 200000 이라 완탐 불가능
DP 불가능 특별상을 수여함으로써 본 상 수여자가 달라지고 점수가 달라진다
그리디라고 판단하여 특별상을 수여할 때 가장 최대 합을 찾으려는 규칙을 찾았다
심판이 준 점수가 낮은 순으로 정렬하여 특별상을 수여하지 않으면 점수에 포함되지 못하는 친구들만 따로 배열을 만들었다
점수가 높은 순으로 정렬하여 특별상 개수만큼 수여했고
나머지 점수는 특별상 기준인 점수를 더하였다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
Node array[] = new Node[N];
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
array[i] = new Node(x, y);
}
// 작은거 부터 정렬
Arrays.sort(array, (e1, e2) -> e1.y - e2.y);
int cnt = 0;
long result = 0L;
ArrayList<Integer> al = new ArrayList<>();
for(int i = 0; i < N; i++) {
if(N - i > K) {
al.add(array[i].x);
} else {
result += array[i].x;
}
}
Collections.sort(al, (e1, e2) -> e2 - e1);
for(int i = 0; i < al.size(); i++) {
if(cnt < M) {
result += al.get(i);
cnt++;
} else {
break;
}
}
System.out.println(result);
}
static class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
}