[백준]가장 긴 증가하는 부분 수열2/12015번/Python/파이썬/이분탐색

heeee·2021년 3월 16일
0

algorithm

목록 보기
119/123
post-thumbnail

💡문제

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.

예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이고, 길이는 4이다.

입력

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.

둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

출력

첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.


예제입력

6
10 20 10 30 20 50

예제출력

4

📖내가 작성한 code

from bisect import bisect_left
n=int(input())
a=list(map(int,input().split()))
d=[a[0]]
for x in a:
    if d[-1]<x:
        d.append(x)
    else:
    	# ex) 1,5,200,10과 같은 경우 x=10일때 d=[1,5,200]이고
        # 이때 200자리에 10이 대신 들어가야한다.
        # 길이를 구하는것이므로 d안의 수는 상관없음
        d[bisect_left(d,x)]=x
print(len(d))

👩

가장 긴 증가하는 부분 수열과 동일하지만 조건이 1,000,000로 늘어났으므로 DP로 풀경우 시간초과O(N^2)
이분탐색을 이용하면 O(NlogN)이므로 통과한다.
이분탐색의 경우, bisect 라이브러리를 사용하면 쉽게 구할 수 있다.

bisect

이진 검색 알고리즘을 이용해서 시퀀스를 검색하고, 시퀀스에 항목을 삽입할수 있는 함수를 제공한다.

bisect_right()는 x와 동일한 값이 시퀀스 a에 존재할 때 x와 동일한 값 바로 뒤 위치를 리턴한다.
반면에 bisect_left()는 x와 동일한 값 위치를 리턴한다.


문제 출처 : https://www.acmicpc.net/problem/12015

0개의 댓글