티스토리 뷰

IOI/IOI2014

[IOI2014 Day2] Holiday 해법

전명우 2015.07.31 18:38

인접한 도시 사이를 이동하는데 걸리는 시간 1, 한 도시에 있는 관광지를 모두 둘러보는 시간 1이 걸리고 시작점이 주어졌을 때, 가장 관광지를 많이 방문하는 문제다. 물론 같은 관광지를 여러 번 방문해서는 안된다.


답이 될 수 있는 이동 경로는 아래 두 가지 중 하나이다.

1) 시작점에서 왼쪽으로 0칸 이상 가다가 어느 순간 오른쪽으로 이동하여, 시작점 보다 오른쪽으로 간다.

2) 시작점에서 오른쪽으로 0칸 이상 가다가 어느 순간 왼쪽으로 이동하여, 시작점 보다 왼쪽으로 간다.

즉, 쉽게 말하자면 방향을 한 번만 바꾼다는 것이다.

두 번 이상 방향을 바꾸어 왔다갔다 하는 것은 이동하는 시간만 늘리므로 항상 안좋다는 것을 알 수 있다.


2번 경우는 전체를 좌우로 뒤집었을 때 1번 경우와 같아지므로, 1번 경우에 대해서 답을 구하는 방법만 설명하겠다.

문제를 해결하기 위해서는 시작점에서 오른쪽으로만 갈 때, $t$ 시간 안에 방문하는 관광지 수의 최대값을 $0 \leq t \leq d$인 모든 $t$에 대해 계산해야한다.

편의상 시작점을 $0$번 도시라고 하자.


어떤 시간 $t$에 대해 방문하는 관광지 수의 최대값을 구하는 방법을 설명하겠다.

$0 \leq i < n$인 모든 $i$에 대해 $i$번 도시까지 이동한다고 했을 때, 방문 가능한 도시는 $t - i$개이며, 가장 관광지 수가 많은 도시들을 먼저 방문하는 것이 좋다. 이 때 방문 가능한 도시 중 관광지 수가 많은 상위 $t - i$개에 대한 합을 세그먼트 트리를 써서 $O(\lg N)$ 에 구하는 것이 가능하다. 

위 알고리즘을 모든 $t$에 대해 하면 $O(N^2 \lg N)$이 걸린다.


$p(t)$를 시간 $t$에 최대로 많은 관광지를 방문할 때 마지막으로 위치한 도시 번호라고 하자. 마지막으로 위치 가능한 도시가 여러 곳일 때, 그러한 도시들 중 가장 왼쪽에 있는 도시라고 하자.

$t_1 < t_2$일 때, $p(t_1) \leq p(t_2)$라는 것을 조금만 생각해보면 알 수 있다.


$0 \leq t \leq d$인 모든 $t$에 대해 최대값을 알아야하는데, 이는 분할정복 비슷한 방법으로 해결할 수 있다.

처음에 $m = \frac{d}{2}$인 $m$에 대해 위에서 말한 알고리즘으로 최대값을 계산하고 $p(t)$도 찾는다. 그러면 $t > m$인 $t$에 대해 위 알고리즘에서 끝 도시의 후보가 $0$번 도시부터 $n-1$번 도시까지가 아닌 $p(t)$번 도시부터 $n-1$번 도시까지로 줄어들고, 마찬가지로 $t < m$인 $t$에 대해 끝 도시의 후보가 $0$번 도시부터 $p(t)$번 도시까지로 줄어들게 된다.

이를 재귀적으로 해결하여 $0 \leq t \leq d$인 모든 $t$에 대해 최대값을 계산할 수 있다. 이 때 시간복잡도는 $O(N {\lg}^2 N)$이다.


위 방법으로 시작점에서 오른쪽으로만 갈 때 가능한 모든 시간 $t$에 대해 최대값을 구했다.

마찬가지로 시작점에서 시작점을 방문하지 않고 왼쪽으로만 갈 때 가능한 모든 시간 $t$에 대해 최대값을 구할 수 있다. 이 때 이동 시간을 1이 아니라 2로 두고 계산한다.

그러면 위에서 계산한 두 값들을 통해 시간 $d$에 대해 가능한 최대값을 계산할 수 있다.


이 처럼 시간복잡도를 줄이는 방법을 Divide & Conquer Optimization이라 한다.


코드 보기


저작자 표시
신고

'IOI > IOI2014' 카테고리의 다른 글

[IOI2014 Day2] Holiday 해법  (0) 2015.07.31
[IOI2014 Day2] Friend 해법  (0) 2014.07.18
[IOI2014 Day2] Gondola 해법  (0) 2014.07.17
IOI2014 Day 2 종료  (0) 2014.07.17
[IOI2014 Day1] Rail 해법  (0) 2014.07.17
[IOI2014 Day1] Game 해법  (1) 2014.07.17
댓글
댓글쓰기 폼