BOJ/๐Ÿฅ‡

โ˜…DP Upper-Advanced I - 9 Solvedโ˜…

metamong 2024. 1. 5.

โ˜… 12015 ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด 2 โ˜…

 

import sys
input=sys.stdin.readline

N=int(input())
A=list(map(int,input().split()))

#binary search
def binary_search(l, x):
    start,end=0,len(l)-1
    while start<=end:
        mid=(start+end)//2
        if x <= l[mid]:
            end=mid-1
            ans=mid
        else:
            start=mid+1
    l[ans]=x
    return l

#LIS
ans=[A[0]]

for x in range(1,N):
    if ans[-1] < A[x]: #just add
        ans.append(A[x])
    else: #searching the spot
        ans=binary_search(ans, A[x])

print(len(ans))

 

๐Ÿœ LIS(O(nlogn)) ๋ฌธ์ œ


โ˜… 12738 ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด 3 โ˜…

 

๐Ÿœ ์ˆ˜์—ด ์›์†Œ๊ฐ€ ์Œ์ˆ˜์—ฌ๋„ LIS(O(nlogn)) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์„ฑ๋ฆฝ


โ˜… 1365 ๊ผฌ์ธ ์ „๊นƒ์ค„ โ˜…

 

import sys
input=sys.stdin.readline

N=int(input())
n=list(map(int,input().split()))

def binary_search(l,x):
    start,end=0,len(l)-1
    while start<=end:
        mid=(start+end)//2
        if x <= l[mid]:
            ans = mid
            end = mid - 1
        else:
            start = mid + 1
    l[ans] = x
    return l

#lis(o(nlogn))
ans=[n[0]]

for x in range(1,N):
    if ans[-1] < n[x]:
        ans.append(n[x])
    else:
        ans=binary_search(ans,n[x])

print(N-len(ans))

 

๐Ÿœ ๊ผฌ์ด์ง€ ์•Š๊ฒŒ lis(O(nlogn)) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ ์šฉ


โ˜… 2352 ๋ฐ˜๋„์ฒด ์„ค๊ณ„ โ˜…

import sys
input=sys.stdin.readline
n=int(input())
l = list(map(int,input().split()))

def binary_search_lis(arr,n):
    start,end=0,len(arr)-1
    while start<=end:
        mid=(start+end)//2
        if n <= arr[mid]:
            ans = mid
            end = mid-1
        else:
            start = mid+1
    arr[ans] = n
    return arr
arr=[l[0]]
for x in range(1,n):
    if arr[-1]<l[x]:
        arr.append(l[x])
    else:
        arr = binary_search_lis(arr,l[x])
print(len(arr))

 

๐Ÿœ ์œ„ 1365 ๊ผฌ์ธ ์ „๊นƒ์ค„๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ. ์ด๋ถ„ํƒ์ƒ‰์„ ํ™œ์šฉํ•œ O(nlogn) LIS ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ ํฌํŠธ ์ตœ๋Œ€ ๊ฐœ์ˆ˜ ๊ตฌํ•˜๊ธฐ


โ˜… 3066 ๋ธŒ๋ฆฌ์ง• ์‹œ๊ทธ๋„ โ˜…

import sys
input=sys.stdin.readline

def binary_search_lis(arr,n):
    start,end=0,len(arr)-1
    while start<=end:
        mid=(start+end)//2
        if n <= arr[mid]:
            ans = mid
            end = mid-1
        else:
            start = mid+1
    arr[ans] = n
    return arr

for _ in range(int(input())):
    N=int(input())
    l = [int(input()) for _ in range(N)]
    arr=[l[0]]
    for x in range(1,N):
        if arr[-1]<l[x]:
            arr.append(l[x])
        else:
            arr = binary_search_lis(arr,l[x])
    print(len(arr))

 

๐Ÿœ ์—ญ์‹œ LIS(O(nlogn))์œผ๋กœ ์œ„ ๋ฌธ์ œ์™€ ๋™์ผ


โ˜… 1818 ์ฑ…์ •๋ฆฌ โ˜…

import sys
input=sys.stdin.readline

def binary_search_lis(arr,n):
    start,end=0,len(arr)-1
    while start<=end:
        mid=(start+end)//2
        if n < arr[mid]:
            ans = mid
            end = mid-1
        else:
            start = mid+1
    arr[ans] = n
    return arr

N=int(input())
l=list(map(int,input().split()))
arr=[l[0]]
for x in range(1,N):
    if arr[-1]<l[x]:
        arr.append(l[x])
    else:
        arr = binary_search_lis(arr,l[x])
print(N-len(arr))

 

๐Ÿœ 1๋ถ€ํ„ฐ N๊นŒ์ง€ ์ฑ…์„ ๊ฐ€์ง€๋Ÿฐํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๊ฐ€์ง€๋Ÿฐํ•˜๊ฒŒ ์ •๋ฆฌํ•œ, ์ฆ‰ ์ฑ… ๋ฒˆํ˜ธ๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„ ์ˆ˜์—ด LIS์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๊ณ (์ด ๋•Œ ์ฑ…์ด ๋„์—„๋„์—„ ์žˆ์–ด๋„ ์ƒ๊ด€ ์—†๋‹ค), ์ „์ฒด ์ฑ…์˜ ์ˆ˜์—์„œ LIS์˜ ๊ธธ์ด๋ฅผ ๋บ€ ๊ฐœ์ˆ˜๋งŒํผ ๋ณธ๋ž˜ ์ž๋ฆฌ์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค. LIS๋ผ๋Š” ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ์„ ๊ธฐ์–ตํ•ด์•ผ ํ•˜๋Š” ์œ ํ˜•. LIS ์‘์šฉ๋ฒ„์ „


โ˜… 3745 ์˜ค๋ฆ„์„ธ โ˜…

import sys
input=sys.stdin.readline

def binary_search_lis(arr,n):
    start,end=0,len(arr)-1
    while start<=end:
        mid=(start+end)//2
        if n <= arr[mid]:
            ans = mid
            end = mid-1
        else:
            start = mid+1
    arr[ans] = n
    return arr


while 1:
    try:
        N=int(input())
        l=list(map(int,input().split()))
        arr=[l[0]]
        for x in range(1,N):
            if arr[-1]<l[x]:
                arr.append(l[x])
            else:
                arr = binary_search_lis(arr,l[x])
        print(len(arr))
    except:
        break

 

๐Ÿœ LIS(Onlogn) ๋ฌธ์ œ


โ˜… 12014 ์ฃผ์‹ โ˜…

import sys
input=sys.stdin.readline

def binary_search_lis(ar,n):
    start,end=0,len(ar)-1
    while start<=end:
        mid=(start+end)//2
        if n <= ar[mid]:
            ans = mid
            end = mid-1
        else:
            start = mid+1
    ar[ans] = n
    return ar

T=int(input())
for i in range(T):
    N,K=map(int,input().split())
    l=list(map(int,input().split()))
    arr=[l[0]]
    for x in range(1,N):
        if arr[-1]<l[x]:
            arr.append(l[x])
        else:
            arr = binary_search_lis(arr,l[x])
    if len(arr)>=K:
        print(f'Case #{i+1}')
        print(1)
    else:
        print(f'Case #{i+1}')
        print(0)

 

๐Ÿœ LIS(Onlogn) ๋ฌธ์ œ


โ˜… 2655 ๊ฐ€์žฅ๋†’์€ํƒ‘์Œ“๊ธฐ โ˜…

import sys
input=sys.stdin.readline

n = int(input())

dp = [[0, []] for _ in range(n)] #[height, [brick_nums listed]]
bricks = []
for i in range(n):
    s,h,w = map(int,input().split())
    bricks.append((s,h,w,i+1))
bricks_sorted = sorted(bricks,key = lambda x : x[0])

#dp initialization
for i in range(n):
    cur_h, cur_num = bricks_sorted[i][1], bricks_sorted[i][3]
    dp[i][0] = cur_h
    dp[i][1] = [cur_num]

for i in range(1,n):
    cur_num = bricks_sorted[i][3]
    cur_w = bricks_sorted[i][2] #check only by w
    cur_h = bricks_sorted[i][1]
    for x in range(i):
        last_brick_num = dp[x][-1][-1]
        last_brick_weight = bricks[last_brick_num-1][2]
        last_brick_height = bricks[last_brick_num-1][1]
        if last_brick_weight < cur_w:
            if dp[i][0] < cur_h + dp[x][0]: #dp update
                dp[i][0] = cur_h + dp[x][0]
                dp[i][1] = dp[x][1] + [cur_num]
dp.sort(key = lambda x: x[0])
print(len(dp[-1][-1]))
print(*dp[-1][1], sep = '\n')

 

๐Ÿœ ์˜ˆ์‹œ์— ์ฃผ์–ด์ง„ (๋ฐ‘๋ฉด S, ๋†’์ด, ๋ฌด๊ฒŒ, ๋ธ”๋ก๋ฒˆํ˜ธ)์ธ ๋ธ”๋ก๋“ค์„ ๋‚˜์—ดํ•ด๋ณด๋ฉด

 

25 3 4 1

4 4 6 2

9 2 3 3

16 2 5 4

1 5 2 5

 

(1) DP ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉ. DP์˜ ๊ตฌ์„ฑ์„ฑ๋ถ„์€ 2๊ฐœ๋กœ ๊ฐ ๋ธ”๋ก์ด ๋ฌด์กฐ๊ฑด ์•„๋ž˜์˜ ๋ธ”๋ก์œผ๋กœ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ์˜ height์™€ ๊ทธ ๋•Œ์˜ ๋ธ”๋ก ๋ฒˆํ˜ธ ์กฐํ•ฉ list(์ฆ‰, LIS์˜ dp์™€ ์™„์ „ํžˆ ๋˜‘๊ฐ™๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค)

 

(2) ์ฆ‰ DP initialization ์œ„ํ•ด ๋ฐ‘๋ฉด S ์˜ค๋ฆ„์ฐจ์ˆœ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ.

 

1 5 2 5

4 4 6 2

9 2 3 3

16 2 5 4

25 3 4 1

 

(3) DP initialization. ์ผ๋‹จ, ๊ฐ dp ๊ตฌ์„ฑ์„ฑ๋ถ„์— ํ•ด๋‹น brick(sorted๋œ brick ๊ธฐ์ค€์œผ๋กœ ์ง„ํ–‰)์ด ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•˜๋ฏ€๋กœ ํ˜„์žฌ brick์˜ height / number dp๋กœ update.

[[5, [5]], [4, [2]], [2, [3]], [2, [4]], [3, [1]]]

 

(4) LIS ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ sorted๋œ bricks ๊ธฐ์ค€์œผ๋กœ ์ด์ค‘ for๋ฌธ(O(n^2)) ๋Œ๋ฉด์„œ ํ˜„์žฌ index i, ์ฆ‰ dp[i]๋ฅผ ์ฑ„์šด๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ, for x in range(i)๋กœ ๋Œ๋ฉด์„œ โ‘  ์•ž์„  brick x์—์„œ์˜ weight๋ณด๋‹ค ํ˜„์žฌ index i์—์„œ์˜ weight๊ฐ€ ๋” ํฌ๊ณ , โ‘ก ํ˜„์žฌ dp[i]์˜ height๋ณด๋‹ค (์•ž์„  brick x์—์„œ์˜ dp[x]์˜ height(์ฆ‰, brick x๋ฅผ ๋ฐ‘๋ฐ”๋‹ฅ์œผ๋กœ ํ–ˆ์„ ๋•Œ์˜ ์ตœ๊ณ  ๋†’์ด) + ํ˜„์žฌ index i์—์„œ์˜ height)๊ฐ€ ๋” ํฌ๋‹ค๋ฉด, dp์˜ ๋‘ ์š”์†Œ update

 

[[5, [5]], [9, [5, 2]], [7, [5, 3]], [9, [5, 3, 4]], [10, [5, 3, 1]]]

 

(5) dp์˜ ๊ตฌ์„ฑ์š”์†Œ ์ฒซ๋ฒˆ์งธ ์ค‘ ์ตœ๋Œ“๊ฐ’์—์„œ์˜ ๋‘๋ฒˆ์งธ ์š”์†Œ brick number์™€ ๋‘๋ฒˆ์งธ ์š”์†Œ์˜ ๊ธธ์ด(the number of bricks) ๊ฐ๊ฐ ์ถœ๋ ฅํ•˜๋ฉด ๋!


 

 

 

 

 

 

 

 

 

 

 

 

 

 

๋Œ“๊ธ€