종식당

[백준 11053, 12015] 가장 긴 증가하는 부분 수열 1, 2 본문

백준

[백준 11053, 12015] 가장 긴 증가하는 부분 수열 1, 2

종식당 2024. 2. 8. 11:28
728x90
반응형

 

https://www.acmicpc.net/problem/11053

 

11053번: 가장 긴 증가하는 부분 수열

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이

www.acmicpc.net

  • 문제 설명

첫 번째 입력으로 수열의 길이를 입력받고 두 번째 줄에 수열을 입력받는다. 출력으로는 증가하는 부분 수열 중에 가장 긴 길이를 출력하면 된다.

 

이 문제 유형의 알고리즘으로는 LIS(Longest Increasing Subsequence)이다. 이 알고리즘에 대해서는 이진 탐색을 공부하면서 처음 알게 되었으며 이 유형의 문제를 푸는 데에 있어서 크게 두 가지 방법이 있다.

  1. Dynamic Programming
  2. 이진 탐색

Dynamic Programming

N = int(input())
A = [*map(int,input().split())]

dp = [1]*N
for i in range(N):
    for j in range(i):
        if A[i] > A[j]:
            dp[i] = max(dp[i],dp[j]+1)
print(max(dp))

 

먼저 dp리스트를 1로 초기화해준다. 그 후 리스트에서 현재 위치(i) 보다 이전에 있는 원소(j)가 작은지 확인한다. 작다면, 현재 위치의 이전 숫자 중, dp 최댓값을 구하고 그 길이에 1을 더해주면 된다. 

 

예를 들어 i = 4일때를 확인해 보자.

i = 4 j = 0 dp[4] =1

arr [4] > arr [0] true 이므로 dp [4] = max(dp [4], dp [0] + 1) 2이다.

i = 4 j = 1 dp[4] = 2

arr [4] > arr [1] false

i = 4 j = 2 dp[4] = 2

arr [4] > arr [2] true이므로 dp [4] = max(dp [4], dp [2] + 1) 2이다.

i = 4 j = 3 dp[4] = 2

arr [4] > arr [3] false

 

dp리스트를 표로 나타내면 다음과 같다.

arr 10 20 10 30 20 50
dp 1 2 1 3 2 4

 

LIS문제를 dp를 이용하여 풀게 되면 O(N^2)의 시간 복잡도를 가진다. 만약 시간을 줄이고 싶다면 이진 탐색으로 풀면 된다.

 

이진 탐색

https://www.acmicpc.net/problem/12015

 

12015번: 가장 긴 증가하는 부분 수열 2

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

www.acmicpc.net

from bisect import bisect_left
N = int(input())
A = [*map(int,input().split())]

dp = [A[0]]
for i in range(N):
    if dp[-1] < A[i]:
        dp.append(A[i])
    else:
        index = bisect_left(dp,A[i])
        dp[index] = A[i]
print(len(dp))

 

이진 탐색 알고리즘에서 배운 bisect_left를 이용하는 방법이다. 처음 dp리스트에 수열의 첫 번째 원소의 값을 저장하고 for문으로 수열을 돌면서 만약 dp리스트의 마지막 값보다 큰 값이면 그냥 dp리스트에 추가해 주고 만약 작거나 같으면 dp리스트에서 해당 값이 들어갈 자리를 bisect_left로 찾아서 dp의 값을 바꾸면 된다. 그러면 최종 dp에는 증가하는 수열만 남게 되고 이의 길이를 출력하면 된다. 이때 시간 복잡도는 O(NlogN)으로 dp보다 훨씬 빠르다.

728x90
반응형

'백준' 카테고리의 다른 글

[백준 2776] 암기왕  (1) 2024.04.02
[백준 1929] 소수 만들기  (0) 2024.02.14
[백준 20291] 파일 정리  (0) 2024.02.01
[백준 1755] 숫자놀이  (2) 2024.01.31
[백준 10814] 나이 순 정렬  (2) 2024.01.31