Processing math: 100%

사용자 도구

사이트 도구


ps:problems:programmers:12984

지형 편집

ps
링크programmers.co.kr/…
출처프로그래머스
문제 번호12984
문제명지형 편집
레벨Level 4
분류

애드혹, 선택 알고리즘

시간복잡도O(n)
인풋사이즈n<=90000
사용한 언어Python
해결날짜2020/12/19

풀이

  • 인풋이 N*N 크기의 2차원 배열로 들어오지만 별 의미는 없다. 길이가 N^2인 1차원 배열로 들어오는 것과 풀이하는 데에는 아무 차이가 없다.
  • 주어진 N^2개의 높이를 정렬한 것을 h라고 하자.
  • 모든 칸의 높이를 x로 맞출때의 비용을 cost(x)라고 하자.
  • 우선, cost(t)를 최소로 하는 t는 h 배열 안에 있는 수이다.
    • 만약 그렇지 않다면, 즉 t가 h[i-1] < t < h[i] 이라면, 모순이 된다는 것을 쉽게 보일수 있다.
      • 초기 상태에서 t보다 낮은 칸의 갯수는 i개, 높은 칸의 갯수는 n2i 개이다
      • h[i1]로 만들때의 비용 cost(h[i1])는, cost(t)에 비해서, i개의 칸은 th[i]만큼 덜 쌓아야 되고, n2i개의 칸은 th[i]만큼 더 깎아야 한다. 그래서
        • cost(h[i1])=cost(t)i×(th[i1])P+(n2i)×(th[i1])Q=cost(t)(th[i1])×((P+Q)iQn2)
      • h[i]로 만들때의 비용 cost(h[i])는, cost(t)에 비해서, i개의 칸은 h[i]t만큼 더 쌓아야 되고, n2i개의 칸은 h[i]t만큼 덜 깎아야 한다. 그래서
        • cost(h[i])=cost(t)+i×(h[i]t)P(n2i)×(h[i]t)Q=cost(t)+(h[i]t)×((P+Q)iQn2)
      • 따라서, (P+Q)iQn2 가 양수이면 cost(h[i1])<cost(t)이고, (P+Q)iQn2 가 음수이면 cost(h[i])<cost(t). 어느쪽이든 cost(h[x])가 cost(t)보다 작거나 같은 x가 존재한다.
  • f(i) = cost(h[i]) - cost(h[i-1]) 라고 하면, 이것은 위에서 했던 것과 비슷한 방법으로 구할 수 있고,
    • f(i)=i(h[i]h[i1])P(n2i)(h[i]h[i1])Q=(h[i]h[i1])((P+Q)iQn2)
    • f(i) >= 0 인 조건은 iQn2P+Q 이다
  • 따라서 cost(h[i])=cost(h[0])+in=1f(n) 가 최대값을 갖는 것은 i=Qn2P+Q 일 때이다.
  • 이렇게 구한 i를 가지고 t=h[i]를 구하면, cost(t)는 배열을 순회하면서 O(n)에 계산 가능하다.
  • 또한, h[i]를 구하는 것은, h를 모두 정렬할 필요도 없이 그냥 i번째로 큰 수만 찾으면 되므로, 이것 또한 이론적으로는 QuickSelect와 같은 선택 알고리즘을 이용해서 O(n)에 구할 수 있고, 전체 시간복잡도는 O(n)이 된다.
    • 그러나 실제 구현은 그냥 O(nlogn)의 built-in sort 함수를 써서 구현했다. python에서는 이편이 O(n)의 선택 알고리즘을 쓰는 것보다 빠르기 때문이다. (선택 알고리즘 참고)

코드

"""Solution code for "Programmers 12984. 지형 편집".

- Problem link: https://programmers.co.kr/learn/courses/30/lessons/12984
- Solution link: http://www.teferi.net/ps/problems/programmers/12984
"""

import itertools


def solution(land, P, Q):
    heights = sorted(itertools.chain.from_iterable(land))
    target = heights[Q * len(heights) // (P + Q)]
    return sum((target - h) * (P if target > h else -Q) for h in heights)

토론

하민수, 2021/03/03 10:08
잘읽었습니다
댓글을 입력하세요:
 
ps/problems/programmers/12984.txt · 마지막으로 수정됨: 2021/01/21 16:07 저자 teferi