오랜만에 마라톤 완주글을 쓰네요. 난이도가 높아지니까 점점 완주하기 어려워 지는 것 같습니다.
A. 어떤 호박의 할로윈 여행
작은 원이 큰 원 속에 들어갈 수 있는 경우, 큰 원이 판보다 작거나 같은지만 판단하면 됩니다. 그렇지 않은 경우 두 원을 나란히 배치했을 때 판보다 작은지, 즉 바깥 반지름의 합이 판의 반지름보다 작거나 같은지만 판단하면 됩니다.
1 |
|
B. 꿍의 여친 만들기
문자열을 잘 파싱해서 조건들의 조합의 시간의 최댓값의 최댓값을 구해주면 됩니다.
1 |
|
C. 타일링
$i$번째 열 까지 채우는 경우의 수를 $dp[i]$라 하면 점화식 $dp[i] = dp[i - 1] + 2dp[i - 2]$을 이용해서 답을 구하면 됩니다. 답이 매우 커질 수 있으므로, 큰 수 연산을 지원하는 언어를 사용하는 것이 편합니다.
1 |
|
D. 걷다보니 신천역 삼
$N$이 충분히 작으므로 백트래킹으로 구하면 됩니다.
1 |
|
E. The ♡ System
먼저 수를 3진법으로 나타낸 뒤, 만약 자릿수가 $2$인 경우 $2 = 3 - 1$이므로 현재 자릿수를 $-1$로 바꾸고 다음 자릿수에 $1$을 더합니다. $-2$인 경우도 마찬가지로 $-2 = -3 + 1$이므로 현재 자릿수를 $1$로 바꾸고 다음 자릿수에 $1$을 뺍니다. 계산 과정에서 자릿수의 절댓값이 $3$을 넘어가면 다음 자릿수로 넘겨주면 됩니다.
1 |
|
F. 이가 빠진 이진 트리
그냥 모든 원소를 정렬한 뒤에 중위 순회로 이진 탐색 트리를 만들고 후위 순회하면 됩니다.
1 |
|
G. 다항식 게임
그냥 다항식의 곱셈을 구현해주면 됩니다.
1 |
|
H. 회의실 배정 4
DP로 시작해서 그리디로 풀어보겠습니다.
회의의 시작 시간을 기준으로, 같다면 끝 시간을 기준으로 오름차순 정렬합니다. 이때 $i$번째 회의의 시작 시간을 $s_i$, 끝 시간을 $e_i$, 사람 수를 $p_i$라 합시다. $dp[i]$를 $i$번째 회의까지 고려하고 $i$번째 회의를 진행했을 때 최대의 사람 수 라고 합시다. $dp[i] = \max_{j < i, e_j \le s_i}(dp[j]) + p_i$로 구할 수 있습니다. 점화식에서 $dp[j]$가 최대로 되는 값은 나중에 $dp[i + 1]$을 구할 때도 재활용 할 수 있습니다. 왜냐하면 $s_i \le s_{i + 1}$이기 때문입니다. 그렇다면 굳이 매번 $\max$ 연산을 해야 할까요? $e_i$를 기준으로 하는 최소 힙에 회의를 넣고 관리하는 방식으로 $dp[j]$의 최댓값을 구할 수 있습니다.
구하려는 문제의 정답 $ans = 0$으로 놓고 $i = 0$부터 $n - 1$까지 탐색합시다. 힙에 담긴 $e_j$가 최소인 회의 $j$가 $e_j \le s_i$를 만족하는 동안 힙에서 회의를 하나 뽑고 $ans = \max(ans, dp[j])$로 갱신합니다. $dp[i] = ans + p_i$로 갱신하고 힙에 회의 $i$를 넣습니다. 반복문이 모두 끝났을 때 힙에 담긴 회의 $i$를 하나씩 빼내어 $ans = \max(ans, dp[i])$로 갱신하면 답을 구할 수 있습니다.
아래 코드에서는 $dp[i] = ans + p_i$로 갱신하는 방식 대신 그냥 $p_i = p_i + ans$로 갱신하고 힙에 회의 자체를 넣는 방식으로 구현했습니다.
1 |
|