https://www.acmicpc.net/problem/2109
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
// 강연 클래스 생성
// 강연 데드라인 오름차순으로, 그게 같다면 강연비 내림차순으로 정렬하도록 함
// PriorityQueue에 강연들을 넣음
// 새로운 PriorityQueue를 생성한 다음, 거기에 처음 PriorityQueue에서 하나씩 빼서 넣음
// 만약 현재 데드라인보다 새로운 PriorityQueue에 있는 값의 개수가 더 많다면
// 데드라인 개수만큼으로 줄임
// 마지막에 남은 수들을 모두 더함
static int n;
static PriorityQueue<Lecture> lectures;
static void input() {
Reader scanner = new Reader();
n = scanner.nextInt();
lectures = new PriorityQueue<>();
for(int lecture = 0; lecture < n; lecture++) {
int pay = scanner.nextInt(), deadline = scanner.nextInt();
lectures.offer(new Lecture(deadline, pay));
}
}
static void solution() {
PriorityQueue<Integer> pays = new PriorityQueue<>();
for(int idx = 0; idx < n; idx++) {
Lecture lecture = lectures.poll();
pays.offer(lecture.pay);
while(!pays.isEmpty() && lecture.deadline < pays.size())
pays.poll();
}
int maxPay = 0;
while(!pays.isEmpty())
maxPay += pays.poll();
System.out.println(maxPay);
}
static class Lecture implements Comparable<Lecture> {
int deadline, pay;
public Lecture(int deadline, int pay) {
this.deadline = deadline;
this.pay = pay;
}
@Override
public int compareTo(Lecture l) {
if(this.deadline != l.deadline) return this.deadline - l.deadline;
return l.pay - this.pay;
}
}
public static void main(String[] args) {
input();
solution();
}
static class Reader {
BufferedReader br;
StringTokenizer st;
public Reader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while(st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}