티스토리 뷰

15678번: 연세워터파크DP


kks227님 블로그의 동적계획법 4를 읽고 인상 깊어 작성하게 되었다.

이 문제는 임의의 시작점에서 번호가 증가하는 방향으로 징검다리를 건너게 되는데

한번에 D개 이하의 징검다리를 뛰어넘을 수 있을 때 점수의 최댓값을 구하는 문제이다.

풀이는 간단하다.

어떤 도착점 k의 관하여 dp(k)를 도착점 k에 도착했을 때 얻을 수 있는 최대 점수라 하면,

dp(k)는 max(0, k-D) ~ k까지의 dp값 중 최댓값이 된다.

이후 모든 i에 대하여 dp(i)의 최댓값이 답이다.


이 때 구간에 대하여 최댓값을 구하는 과정을 반복하여야 한다.

구간이기에 구간 트리를 이용하여 O(lgN)만에 최댓값을 찾을 수 있고

이는 시간복잡도가 O(NlgN)만에 문제를 해결할 수 있다.


이 때 kks227님의 블로그에서는 덱을 이용하여 이 문제를 O(N)만에 풀게 되는데

덱 안에 우리가 알고 싶은 부분의 가장 긴 감소하는 부분수열의 정보를 넣어 이 문제를 해결한다.

매 단계마다 가장 긴 감소하는 부분수열이 들어있다면

덱에 가장 앞에 있는 값이 최댓값을 가르키는 인덱스일 것이고,

인덱스가 max(0, k-D)를 넘어 갈 경우 이 원소를 빼었을 때도 덱에는 그 원소 다음으로 큰 것이

들어있기에 해결이 가능한 것이다!

아래와 같은 순서로 정리할 수 있다.


1. 덱의 앞에 들어있는 인덱스가 k-D보다 작다면 버린다.

2. dp(k) = 덱의 앞에 들어있는 값이 가르키고 있는 최대값 + k에 도착했을 때 얻을 수 있는 점수

3. 덱의 뒤에서 dp(k)보다 작은 점수가 있다면 버린다.

4. 덱의 뒤에 dp(k)와 인덱스 정보를 넣는다.


이렇게 구간의 최댓값 또는 최솟값을 구하는 방법으로 쓰일만한 테크닉인 것 같다.

덱으로 풀 수 있는 문제가 있다니..! 정말 많은 도움이 되었습니다. 감사합니다.

'문제 해결 > 백준 온라인 저지' 카테고리의 다른 글

14577번: 일기 예보  (0) 2019.01.06
12995번: 트리나라  (0) 2019.01.05
1787번: 문자열의 주기 예측  (0) 2018.09.26
1017번: 소수 쌍  (0) 2018.09.26
14961번: Untangling Chain  (0) 2018.09.09
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday