티스토리 뷰


문제

문제 분류

  • 난이도 - 중
  • 태그 - dynamic programming, data structure, segment tree

문제 풀이

내부 반지름의 길이 \(a_i\), 외부 반지름의 길이 \(b_i\), 그리고 높이 \(h_i\)가 주어진 여러 개의 링들을 최대한 높게 쌓는 문제다. 일단 아래와 같이 2차원 평면으로 보면 (1) \(b_i\)가 증가하는 순으로, (2) \(b_i\)가 증가하는 순으로 정렬해야할 필요성을 느낄 수 있다.


완전 탐색을 할 경우 \(O(2^n)\)으로 문제를 해결할 수 있다. 너무 느리므로 동적계획법을 고민해보면 아래와 같은 점화식을 찾을 수 있다.


\(dp[i]\): \(i\)번 링을 맨 밑으로 하여 쌓을 수 있는 최대 높이 (단, 위에서 언급한대로 정렬되어 있어야 한다)


\(dp[i]=\underset {j < i \ and \ a_i < b_j}{max}(dp[j]) + h_i\)


위 점화식을 반복문을 이용하여 계산하면, \(O(n^2)\)에 문제를 해결할 수 있지만, 역시 정답을 내기에는 부족하다. 하지만 잘보면 위 식에서 \(dp[i]\)를 계산할 때, 이미 계산된 값 \(dp[j] \ (j < i)\) 중 \(a_i < b_j\)인 \(dp[j]\)의 최댓값을 찾는다. 이 값은 구간 트리를 이용하면 빠르게 계산할 수 있다.

각 \(a_i\)와 \(b_i\)의 값들을 가지고 구간 트리를 만든 뒤, \(dp[i]\)에 해당하는 값을 구간 트리의 구간 (index(\(a_i\)), index(\(b_i\))]에 쿼리를 통해 찾은 값에 \(h_i\)를 더해 계산하고, \(b_i\)에 해당하는 위치(index(\(b_i)\))에 저장해두면 된다.

※ 여기서 index(x)는 구간 트리내에서 x값에 해당하는 원소의 번호이다. 

소스 코드



'알고리즘 문제 풀이' 카테고리의 다른 글

CF 785E Anton and Permutation  (0) 2017.03.27
평방 분할 기법 (Square Root Decomposion Technique)  (0) 2017.03.27
777D Cloud of Hashtags  (0) 2017.03.01
777C Alyona and Spreadsheet  (0) 2017.03.01
BOJ 1034 램프  (0) 2017.02.28
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함