목차
문제 : boj11912
필요 알고리즘
- 그리디 알고리즘
- 규칙만 찾으면 쉽게 접근 가능하다.
※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.
풀이
아이디어만 떠오르면 어렵지 않은 문제이다. 말이 있을 때, 격자를 놓을 수 있는 경우의 수를 생각해보자. 사실 이것만 생각나면 끝인 문제이다.
1. 첫 번째 말 앞에 1개의 격자를 두는 경우 -> 문제 내에서 1번만 가능
2. 마지막 말 뒤에 1개의 격자를 두는 경우 -> 문제 내에서 1번만 가능
3. 말과 말 사이에 2개의 격자를 두는 경우 -> 말이 k마리라면 k-1번 가능
따라서 위에서 '1'과 '2'는 한번씩만 가능하므로, 칸막이 수 d가 특정 수치까지 남을 때까지는 최대 k-1번 가능한 '3'을 진행해주면 된다. 이 경우 k-1개의 '3'의 경우 중 어떤걸 선택해야 할까? 간격이 큰거부터 계속 골라나가면 된다! '특정 수치'는 몇일까? 3이하로 남기 전까지 진행하면 된다.
long sum = 0;
while (d>3 && !pq.isEmpty()) {
sum+=pq.poll();
d-=2;
}
왜 d=3 이하일 경우는 별도로 봐야 할까? 아래의 경우의 수가 있기 때문이다.
- d=1 인 경우 '3'은 진행이 불가하다. '1'과 '2' 중 큰 쪽을 선택해야 한다.
- d=2 인 경우 '1'+'2' 와 '3'을 더 진행하는 것 중 큰 쪽을 선택해야 한다.
- d=3 인 경우 '3'+'1' 과 '3'+'2'와 '1'+'2' 중 큰 쪽을 선택해야 한다.
if (d==1) {
sum += Math.max(s, e);
} else if (d==3) {
sum += Math.max(s+e, pq.isEmpty()?0:pq.poll()+(Math.max(s,e)));
} else {
sum += Math.max(s+e, pq.isEmpty()?0:pq.poll());
}
코드 : github
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 1<<16);
public static void main(String[] args) throws Exception {
new Main().solution();
}
private void solution() throws Exception {
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
long cur = Integer.parseInt(st.nextToken());
long s = cur-1;
if (s < 0) s = 0;
PriorityQueue<Long> pq = new PriorityQueue<>(Collections.reverseOrder());
while (--k>0) {
long tmp = Integer.parseInt(st.nextToken());
pq.add(tmp-cur-1);
cur = tmp;
}
long e = n-cur;
long sum = 0;
while (d>3 && !pq.isEmpty()) {
sum+=pq.poll();
d-=2;
}
if (d==1) {
sum += Math.max(s, e);
} else if (d==3) {
sum += Math.max(s+e, pq.isEmpty()?0:pq.poll()+(Math.max(s,e)));
} else {
sum += Math.max(s+e, pq.isEmpty()?0:pq.poll());
}
System.out.println(sum);
}
}
'PS > BOJ' 카테고리의 다른 글
[자바] 백준 28251 - 나도리합 (java) (0) | 2023.08.11 |
---|---|
[자바] 백준 17616 - 등수 찾기 (java) (0) | 2023.08.11 |
[자바] 백준 2138 - 전구와 스위치 (java) (0) | 2023.08.11 |
[자바] 백준 11066 - 파일 합치기 (java) (0) | 2023.08.10 |
[자바] 백준 14550 - 마리오 파티 (java) (0) | 2023.08.09 |
댓글