Notion에서 작성된 글이라, 여기 에서 더 깔끔하게 보실 수 있습니다! 😮😊
[징검다리] Parametric Search + Greedy
💡 Parametric Search
- 매개변수에 따른 결과의 단조성 (정렬된 형태)
- 매개변수
mid
를 무엇으로 설정해야할지 전혀 감이 잡히질 않는다면, 최적화하고자 하는 값으로
def solution(distance, rocks, n):
def check(mid):
cnt = prev = 0
for r in rocks:
if r-prev < mid: cnt += 1
else: prev = r
if cnt > n: return False
return True
rocks.sort()
rocks.append(distance)
lo, hi = 1, distance
while lo <= hi:
mid = (lo+hi)//2
if check(mid):
lo = mid+1
else:
hi = mid-1
return hi
결정 문제로 변환
(설명의 편의를 위해, 각 지점 사이의 거리를 ‘간격’ 이라고 표현했습니다.)
[1, 2, 4, 8, 9]
이고, 가 3이라고 가정해 보자.4
이다.4
를 선택하면, 다음으로 이상의 간격을 가진 바위로 8
을 선택할 수 있다.4
를 제거하고 8
을 먼저 선택했다면, 더 이상 선택할 수 있는 바위가 없게 된다.def solution(distance, rocks, n):
def check(mid):
cnt = prev = 0
for r in rocks:
if r-prev < mid: cnt += 1
else: prev = r
if cnt > n: return False
return distance-prev >= mid
rocks.sort()
cnt
를 증가시킨다. 최소 간격 를 유지하는 바위는 제거하지 않고 그 다음 지점의 탐색의 기준이 된다.False
를 return해버리면 결과의 단조성이 깨진다. (똑같이 번 깨면서도 어떤 상황에서는 False
, 어떤 상황에서는 True
가 return된다.prev
바위를 깨고, 그럼에도 번보다 많이 깼는지 확인해주는 것이 결과의 단조성을 유지시켜준다.rocks
의 맨 뒤에 도착점에 해당하는 distance
를 이어붙여준다.prev
를 깨지 않고 유지하면 안되고 깨야 간격의 최솟값 를 만족한다는 것을 의미한다. 따라서, 깨도록 두고 그래도 이하라면 True
를 return한다.if distance-prev < mid:
cnt += 1
이분 탐색 적용
distance
이므로 로 이분 탐색을 진행한다.