알고리즘/search

이분탐색 upperbound, lowerbound 정석#2343기타레슨

씩씩한 IT블로그 2022. 3. 6. 16:55
반응형

upperbound, lowerbound

1. 정의

upperbound : 처음으로 target 초과의 값이 나오는 것!

lowerbound : 처음으로 target 이상의 값이 나오는 것!

 

2. 예시

target이 3일때

lowerbound numbers upperbound
  5 v
  3  
  3  
v 3  
  2  
  1  

 

3. 문제에서의 활용

대부분의 lowerbound, upperbound 문제는 trade-off 관계에 있는 두 값(1.최소최대화 조건, 2.제한조건)이 주어진다.

이를 표로 정리하면 다음과 같다

lowerbound 1. 최소최대화 조건 2.제한 조건 upperbound
  c 5 v
  b 3  
    3  
v a 3  
    2  
    1  

제한조건=3에서 최솟값을 찾아야 하면 lowerbound를 사용하여 최솟값인 a를 찾고,

최댓값을 찾아야 하면 upperbound를 사용하여 c를 찾고 -1을 더해줘서 최댓값인 b를 찾아준다.

2.제한조건은 보통 "1.최소최대 조건"을 input으로 하는 모듈의 return값으로 처리를 한다.

 

3. 예제(백준 2343 기타레슨)



위 예제의 trade-off 관계의 두 값은 블루레이의 길이(최소화조건)와 블루레이의 개수(제한조건)이다.

주어진 블루레이의 개수 조건을 만족하면서 블루레이의 길이를 최소화 해야한다.

이를 표로 나타내면 다음과 같다.

구해야 하는것 블루레이 길이 블루레이 개수
  45 [ (1,2,3,4,5,6,7,8,9) ] 1
  44 [ (1,2,3,4,5,6,7,8),(9) ] 2
  ... ...
  23 [ (1,2,3,4,5,6),(7,8,9) ] 3
  ... ...
v (=제한조건 3의 lowerbound) 17 [ (1,2,3,4,5),(6,7),(8,9) ] 3
  ...  
  12 [ (1,2,3,4),(5,6),(7),(8),(9) ] 5
  11 [ (1,2,3,4),(5,6),(7),(8),(9) ] 5
  10 [ (1,2,3,4),(5),(6),(7),(8),(9) ] 6
  9  [ (1,2,3),(4,5),(6),(7),(8),(9) ] 6

즉 이 문제는 lowerbound 문제이다.

하지만 이해를 돕기위해 lowerbound와 upperbound로 각각의 방법으로 풀어 본다.

 

lowerbound

1. 풀이

블루레이 개수가 3이면서 블루레이의 최소크기를 찾는것은, (블루레이 개수=3)인 lowerbound를 찾는것과 같은 문제가 된다.

<=> 처음으로 3이상이 나오는 부분

 

2. 코드

import sys

N,M=map(int,input().split())
L=list(map(int,sys.stdin.readline().split()))

def cnt_blue(max_len):
    now_len=0
    cnt_blue=1

    for size in L:
        if max_len<size+now_len:
            now_len=size
            cnt_blue+=1
        else:
            now_len+=size

    return cnt_blue

def lower_bound(target):
    top = sum(L)
    bot = max(L)

    while(bot<top):
        mid = (bot+top)//2
        # print(bot, mid,top)
        if target < cnt_blue(mid):
            bot = mid+1
        else:
            top = mid

    print(bot)

lower_bound(M)

 

3. 핵심

if target < cnt_blue(mid):
            bot = mid+1
        else:
            top = mid

타겟(3)보다 클때만 bot을 밀어올린다.

=> 그럼 3의 가장 아래부분이 찾아진다.

 

upperbound

1. 풀이

블루레이 개수가 3이면서 블루레이의 최소크기를 찾는것은, (블루레이 개수=4)인 upperbound를 찾는것과 같은 문제가 된다.

<=> 처음으로 3이상이 나오는 부분

 

2. 코드

import sys

N,M=map(int,input().split())
L=list(map(int,sys.stdin.readline().split()))

def cnt_blue(max_len):
    now_len=0
    cnt_blue=1

    for size in L:
        if max_len<size+now_len:
            now_len=size
            cnt_blue+=1
        else:
            now_len+=size

    return cnt_blue

def upper_bound(target):
    top = sum(L) + 1
    bot = max(L)

    while(bot<top):
        mid = (bot+top)//2
        if target+1<=cnt_blue(mid):
            bot = mid+1
        else:
            top = mid

    print(bot)

upper_bound(M)

 

3. 핵심

if target+1<=cnt_blue(mid):
            bot = mid+1
        else:
            top = mid

타겟(4)보다 크거나 같을때에도 bot을 밀어올린다.

=> 그럼 3의 가장 아래부분이 찾아진다.

*  제한조건 제일 윗부분의 upperbound는 없으므로 시작할때 top에는 +1을 꼭 해준다(top = sum(L) + 1)

반응형