โ 14003 ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ๋ถ๋ถ ์์ด 5 โ
import sys
input=sys.stdin.readline
N=int(input())
A=list(map(int,input().split()))
#binary search
def binary_search(l, i, 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
i.append(ans+1)
return l, i
#LIS
ans_i=[1]
ans_num=[A[0]]
cur_ans_l=1
LIS=[]
for x in range(1,N):
if ans_num[-1] < A[x]: #just add
cur_ans_l+=1
ans_i.append(cur_ans_l)
ans_num.append(A[x])
else: #searching the spot
ans_num,ans_i=binary_search(ans_num, ans_i, A[x])
LIS_length = len(ans_num)
print(LIS_length)
for i in range(len(ans_i)-1,-1,-1):
if LIS_length == 0:
break
if ans_i[i] == LIS_length:
LIS.append(A[i])
LIS_length-=1
print(*reversed(LIS))
โน๏ธ LIS์ ๊ธธ์ด์ ๋ด์ฉ์ O(nlogn) ์๊ฐ ๋ณต์ก๋ ์ด๋ด๋ก ๊ตฌํ๋ ๊ต๊ณผ์ ๋ฌธ์ . LIS์ ๊ธธ์ด๋ ans_num list์์ binary search๋ก updateํ๋ฉฐ ๋ด์ฉ ์ถ๊ฐ. LIS์ ๋ด์ฉ์ ans_i list์์ ์์ binary search๋ก ์ฝ์ ๋๋ ์์์ index๋ฅผ updateํ๋ฉฐ ๊ฑฐ๊พธ๋ก ์ต๋๊ฐ๋ถํฐ 1์ด ๋ ๋๊น์ง ํด๋น ๋๋ index์ list ์์ ์์ด. ์์ธํ ๋ด์ฉ์ LIS ํฌ์คํ ์ฐธ์กฐ
โ 23035 ๊ฐํจ๋ฆญ๋๋ ๊ณ ์์ด๋ฅผ ์ฌ๋ํด โ
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,M=map(int,input().split())
cats=[]
T=int(input())
for _ in range(T):
r,c=map(int,input().split())
if 0<=r<=N and 0<=c<=M:
cats.append((c,r))
cats=sorted(cats,key=lambda x: (x[0],x[1]))
n=len(cats)
dp=[cats[0][1]]
for i in range(1,n):
if dp[-1]<=cats[i][1]:
dp.append(cats[i][1])
else:
dp=binary_search_lis(dp,cats[i][1])
print(len(dp))
โน๏ธ ์ค๋ณต์ ํ์ฉํ๋ ๋ณํ LIS(Longest Increasing Subsequence) "LNDS(Longest Non-Decreasing Subsequence)" ๋ฌธ์ .
โน๏ธ ์์ ๋ถ์
: ์ ์ฒซ๋ฒ์งธ ์์๋ก ์ฃผ์ด์ง ๊ณ ์์ด์ ์์น๋ฅผ y๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ - ์ดํ x๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ๋ฉด ์๋์ ๊ฐ๋ค.
โ โ y๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ → x๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ
: ์ฟ ๊ธฐ๋ ๋ฌด์กฐ๊ฑด ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ค์๊ด๊น์ง ์ด๋ํ๋ค๊ณ ๊ฐ์ ํ๋ค. ๋ฐ๋ผ์, ์ฟ ๊ธฐ๋ y์ขํ๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ณ์ ์ฆ๊ฐํ๋ ๋ฐฉํฅ(์๋๋ก ๋ด๋ ค๊ฐ๋ ๋ฐฉํฅ) & x์ขํ ๊ธฐ์ค์ผ๋ก ๊ณ์ ์ฆ๊ฐํ๋ ๋ฐฉํฅ(์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ๋ ๋ฐฉํฅ)์ผ๋ก๋ง ์ด๋ํ๋ค.
์ด๋, y์ x ์ขํ ๊ธฐ์ค ๋ ๋ฐฉํฅ ๋ชจ๋ ๋น๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ ํด์ผํ๋ค๋ ๋ป. y๊ธฐ์ค์ผ๋ก ์ผ๋จ ๋น๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ ํ, ๋์ผ y์ขํ๋ฅผ ๊ฐ์ง ๊ณ ์์ด๊ฐ ์๋ค๋ฉด(๋์ผํ ์์น๋ฅผ ๊ฐ์ง 2๋ง๋ฆฌ ์ด์์ ๊ณ ์์ด๋ ์กด์ฌํ์ง ์๋๋ค ๊ฐ์ ), x ๊ธฐ์ค ๋น๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ ํ์.(์ (x,y) (1,6), (5,6) ํด๋น)
โ โก y ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋ ์ฌ๋ฌ x์์ LNDS์ ๊ธธ์ด ์ฐพ๊ธฐ
: ๋ฌด์กฐ๊ฑด y๋ ๋น๋ด๋ฆผ์ฐจ์์ผ๋ก ์ฟ ๊ฑฐ๊ฐ ์ด๋ํ๋ ์ํ์์ x๊ฐ ๋น๋ด๋ฆผ์ฐจ์์ผ๋ก ๋์ด ์๋ ๊ณ ์์ด๋ค์ ๋ฐฅ์ ์ฑ๊ฒจ์ค ์ ์๋ค. ๋ฐ๋ผ์, ์ด๋ ์ โ ๋ก ์ธํด ์ ๋ ฌ๋ ํ์ x์์ LNDS์ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ฉด ๋๋ค.
โ โข ๊ด๊ฑด์, y๋ ๋ค๋ฅด๋ ๋์ผํ x์ ์์นํด ์๋ ๊ณ ์์ด๋ค ๊ณ ๋ ค ํ์
: ์ ํ์ ์ธ LIS ์๊ณ ๋ฆฌ์ฆ์ '์ฆ๊ฐ'ํ๋ ๋ถ๋ถ์์ด์ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ํ์ง๋ง, ์ (x,y) (2,1) / (2,2)์ ๊ฐ์ด x๊ฐ ๋์ผํ, ์ฆ ๊ฐ๋ก ๋ฐฉํฅ์ผ๋ก ๋์ผํ๊ฒ ์์นํด ์์ ์ ์๋ค. ์๋ ์์ ๊ทธ๋ฆผ์ ํ์ธํ์.
: ๋์ผํ y(์ธ๋ก์ถ)์ ๋ ๋ง๋ฆฌ ์ด์์ ๊ณ ์์ด๊ฐ ๋ค๋ฅธ x๋ก ์์นํด ์๋ ๊ฒฝ์ฐ์ด๋ค. ์ด ๋, ๋์ผํ y(2)์ ์๋ ๋ ๊ณ ์์ด(1, 2) ๋ชจ๋ ๋ฐฅ์ ์ฃผ๊ณ , ๊ทธ ๋ค์ y(3)๋ก ๋ด๋ ค๊ฐ๋ค. ์ด ๋, ์ด์ x(2)์ ๊ฐ์๋ y๋ก ๋ด๋ ค๊ฐ๊ธฐ ๋๋ฌธ์ ๋ฐฅ์ ์ค ์ ์๋ค. ๋ฐ๋ผ์ ์ ํ์ ์ธ LIS ์๊ณ ๋ฆฌ์ฆ ์ฝ๋๋ฅผ ๋ณํํ '๊ฐ์ฅ ๊ธด ๋น๋ด๋ฆผ์ฐจ์ ์์ด'์ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ค. ๋ฐ๋ผ์ ์ ํ์ ๊ฐ์ด ๋นจ๊ฐ์ ์ซ์ 1, 2, 2, 2, 3 ์ด 5๋ง๋ฆฌ์๊ฒ ๋ฐฅ์ ๋จน์ผ ์ ์๋ค.
Q. ๋ฌด์กฐ๊ฑด ๋์ผ y์์ ๋ชจ๋ x์ ๊ณ ์์ด๋ฅผ ๋จน์ด๋๊ฒ ๊ฐ์ฅ ๋ง์ ๊ณ ์์ด๋ฅผ ๋จน์ผ ์ ์์๊น? ๋์ผ x ๋ฐฉํฅ์ธ ์๋ ๋ฐฉํฅ์ผ๋ก ๋ด๋ ค๊ฐ์ ๊ณ ์์ด๋ฅผ ๋จน์ด๋ฉด ์๋ ๊น?
A: ์ฆ ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด, ๋นจ๊ฐ์์ผ๋ก ์ด๋ํ๋ฉด 4๋ง๋ฆฌ๋ง ๋จน์ผ ์ ์๊ณ , ํ๋์์ผ๋ก ์ด๋ํ๋ฉด 5๋ง๋ฆฌ๋ฅผ ๋จน์ผ ์ ์๋ค. ๋ฐ๋ผ์ ๋ฌด์กฐ๊ฑด ์ โ ๋๋ก ์ ๋ ฌ์ด ์ต์ ์ ํด๋ฅผ ๋ณด์ฅํ์ง๋ ์์์ ์ ์ ์๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ์ ๊ทธ๋ฆผ case๊น์ง ์ ์ฉํ ํ์ด๋ฅผ ์๊ฐํด๋ผ ์ ์์๊น? ์ ๋ต์ LIS(Onlogn)์ dp array ๊ตฌ์ฑ์ ์๋ค.
: LIS(Onlogn)์ ๊ธธ์ด๋ฅผ ๊ตฌ์ฑํ ๋ ์ต์ข dp array์ ๊ตฌ์ฑ ๋ด์ฉ์ ์ค์ LIS์ ๋ด์ฉ๊ณผ ๋ค๋ฅด๋ค. ์๋ ๊ทธ๋ฆผ ์ฐธ๊ณ .
: ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด, ์ฐ๋ฆฌ๋ LIS์ '๊ธธ์ด'๋ง ๊ถ๊ธํ๋ฏ๋ก, ์ค์ ์ต์ข update๋ dp array๋ [2, 10, 40, 80]์ผ๋ก ์๋ ๊ตฌ์ฑ๋ 10 - 2 - 40 - 80 ์์์ ๋ค๋ฅด๋ค. ์ฆ, LIS dp array๋ฅผ updateํ๋ ๊ณผ์ ์์ ์ ์ง๋ฌธ์ ์ค๋ง๋ฆฌ๋ฅผ ์ป์ ์ ์๋ค.
ex) [8, 10, 14, 10]์ด ์๋ค๋ฉด
(1) ๋ณธ๋ LIS(Onlogn) ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฝ์ฐ ์ด๋ถ ํ์์์ n<= arr[mid] ๋ถ๋ฑ์์ผ๋ก ๋ฐ๊ฟ ์์น ans index๋ฅผ ์ ๋ฐ์ดํธ ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด 10 ๋์ ์๋ก์ด 10์ด ๋ค์ด๊ฐ [8, 10, 14] ์์ฑ
(2) ๋ณํ ์ค๋ณต ํ์ฉ LNDS(Onlogn) ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฝ์ฐ ์ด๋ถ ํ์์์ n<arr[mid] ๋ถ๋ฑ์์ผ๋ก ๊ธฐ์กด 14 ๋์ ์๋ก์ด 10์ด ๋ค์ด๊ฐ [8, 10, 10]์ด ์์ฑ๋๋ค.
์ด๋ ์ฆ๊ฐ์์ด์ด ์๋๋ผ ์ค๋ณต ํ์ฉ ๋น๋ด๋ฆผ์ฐจ์์ ์ต์ฅ ๊ธธ์ด๋ฅผ ๊ตฌํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ค๋ณต ํ์ฉ ๋น๋ด๋ฆผ์ฐจ์์ด๋ผ๋ฉด, ์ค๋ณต์ ํ์ฉํ๊ธฐ ๋๋ฌธ์ dp array์ ๋งจ ๋ ์์๊ฐ 14๊ฐ ์๋๋ผ ์ค๋ณต์ผ๋ก 10์ ๋ถ์ด๋๊ฒ ๋ง๊ธฐ ๋๋ฌธ.
: ์ ์์์ ์๋ฆฌ๋ฅผ ๋ค์ ์ ๊ณ ์์ด ๊ทธ๋ฆผ์ ์ ์ฉํ์๋ฉด, xํ์ธ ๊ณ ์์ด(2) ๋์ ๊ทธ ๋ค์ ์ค ๊ณ ์์ด(1)๊ฐ (์ค๋ณต ํ์ฉ์ด๋ฏ๋ก ์๋ ๊ณ ์์ด(1) ๊ทธ ๋ค์์ ์๋ ๋๋ค.) ๋ค์ด๊ฐ๋ค. ์ด๋ ๊ณง, ๊ฐ์ ์ค์ ์๋ ๊ณ ์์ด๋ฅผ ๋จน์ผ ์ ์๋ค๋ ๋ฌธ์ (์ค๋ณต ํ์ฉ ๋น๋ด๋ฆผ์ฐจ์ ์ต์ฅ ๊ธธ์ด ๊ตฌํ๊ธฐ ์๊ณ ๋ฆฌ์ฆ) ๋ด์ฉ๊ณผ ์ผ๋งฅ์ํตํ๋ค. ํ์ฌ ์์น์์ ๋ค๋ก ๊ฐ ์ ์์ง๋ง, ๊ฐ์ ์ค์ ์๋ ๊ณ ์์ด๊ฐ ์๋ค๋ฉด ์ค๋ณต ํ์ฉํด์ ans๋ฅผ updateํด์ฃผ๋ ์๋ฆฌ๊ฐ ์ด ๋ฌธ์ ์ ํต์ฌ!
โ โฃ ๋ณํ LNDS(Longest Non-Decreasing Subsequence) (Onlogn) ์ผ๋ถ ์ฝ๋
(1) update dp array์ ๋งจ ๋ ์์๋ณด๋ค ํฌ๊ฑฐ๋ '๊ฐ๋ค'๋ฉด array์ ์ถ๊ฐ
dp=[cats[0][1]]
for i in range(1,n):
if dp[-1]<=cats[i][1]:
dp.append(cats[i][1])
else:
dp=binary_search_lis(dp,cats[i][1])
(2) update dp array์ ๋งจ ๋ ์์๋ณด๋ค ์๋ค๋ฉด, binary searching์์ n์ด ์์ ๋ณด๋ค ํฐ ์์ ์ค ๊ฐ์ฅ ์์ ์์ ๋์ (ํฌ๊ฑฐ๋ ๊ฐ์ ์์ x) ๋์ฒด
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
โ 2568 ์ ๊น์ค - 2 โ
import sys
input=sys.stdin.readline
def binary_search_lis(arr,arr_i,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
arr_i.append(ans+1)
return arr,arr_i
N=int(input())
AB=[]
for _ in range(N):
a,b=map(int,input().split())
AB.append((a,b))
AB=sorted(AB,key= lambda x:(x[0]))
values=[x[1] for x in AB]
arr=[values[0]]
arr_i=[1]
cur_i=1
for x in range(1,N):
if arr[-1] < values[x]:
cur_i+=1
arr.append(values[x])
arr_i.append(cur_i)
else:
arr,arr_i=binary_search_lis(arr,arr_i,values[x])
print(N-len(arr))
LIS_length=len(arr)
remove_idxs=[]
for x in range(N-1,-1,-1):
if arr_i[x] == LIS_length:
LIS_length-=1
else:
remove_idxs.append(x)
remove_idxs.sort()
for idx in remove_idxs:
print(AB[idx][0])
โน๏ธ ์ ๋ด๋ A๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ ํ ์ ๋ด๋ B์ LIS(Onlogn)๋ฅผ ๊ตฌํ๋ ๋ฌธ์ . ์ด ๋ LIS์ ๋ด์ฉ๊น์ง ์ถ๋ ฅํด์ผ ํ๋ฏ๋ก LIS index ์ญ์ถ์ ๊น์ง ๊ณ ๋ ค. ์ 14003 ๋ฌธ์ ์ ๋์ผ
โ 1974 Jump Jump Championship โ
import sys
input=sys.stdin.readline
#binary search
def binary_search(l, i, 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
i.append(ans+1)
return l, i
for _ in range(int(input())):
N=int(input())
A=list(map(int,input().split()))
#LIS
ans_i=[1]
ans_num=[A[0]]
cur_ans_l=1
LIS_i=[]
for x in range(1,N):
if ans_num[-1] < A[x]: #just add
cur_ans_l+=1
ans_i.append(cur_ans_l)
ans_num.append(A[x])
else: #searching the spot
ans_num,ans_i=binary_search(ans_num, ans_i, A[x])
LIS_length = len(ans_num)
print(LIS_length)
for i in range(len(ans_i)-1,-1,-1):
if LIS_length == 0:
break
if ans_i[i] == LIS_length:
LIS_i.append(i+1)
LIS_length-=1
print(*reversed(LIS_i))
โน๏ธ LIS(Onlogn)์ ๊ธธ์ด์ ์ญ์ถ์ ๊ฒฝ๋ก ์ถ๋ ฅ ์ ํ์ ์ธ ๋ฌธ์
'BOJ > ๐ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
โ Divide & Conquer Expert(Easy) I - 1 Solvedโ (2) | 2024.06.30 |
---|---|
โ ์ ๋ ฌ ์ต์๊ธ1 - 1๋ฌธ์ ()โ (0) | 2023.02.07 |
๋๊ธ