코딩테스트

[백준] 1053번 - 가장 긴 증가하는 부분 수열

miniberry 2026. 3. 13. 15:03

1) 문제

수열 A가 주어졌을 때 가장 긴 증가하는 부분 수열의 길이를 구하는 문제이다.

예시

A = {10, 20, 10, 30, 20, 50}
 

가능한 증가 부분 수열 중 하나

10 → 20 → 30 → 50
 

따라서 정답은 4이다.

여기서 중요한 점은 "연속된 수열이 아니라 부분 수열"이라는 점이다.

즉 중간 값을 건너뛰어도 된다.


2) 처음 접근 (실패했던 아이디어)

처음에는 다음과 같이 2차원 DP를 생각할 수도 있다.

dp[i][j] = i까지 고려했을 때 j를 선택한 경우
 

하지만 이렇게 설계하면

  • 상태 수가 불필요하게 많아지고
  • 문제 해결에 필요하지 않은 정보까지 저장하게 된다.

LIS 문제에서는 사실 마지막 원소만 알면 충분하다.

그래서 1차원 DP로 해결하는 것이 정석적인 방법이다.


3) 핵심 아이디어

DP 배열을 다음과 같이 정의한다.

dp[i] = i번째 원소를 마지막으로 하는 가장 긴 증가 부분 수열의 길이
 

예를 들어 arr[i] = 30 이라면

... → 30
 

으로 끝나는 LIS 길이를 의미한다.


4) 점화식

i 이전의 원소들을 확인하면서 현재 값보다 작은 경우만 이어붙일 수 있다.

조건

arr[j] < arr[i]

점화식

dp[i] = max(dp[i], dp[j] + 1)

초기값

dp[i] = 1

자기 자신만 선택하는 경우이다.


5) Python 구현

 
import sys
input = sys.stdin.readline

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

dp = [1] * n

for i in range(n):
    for j in range(i):
        if arr[j] < arr[i]:
        	dp[i] = max(dp[i], dp[j] + 1)

print(max(dp))
 

6) 시간 복잡도

이 풀이의 시간복잡도는 O(N^2)이다.

문제 조건 N ≤ 1000 이므로 충분히 통과 가능하다.

'코딩테스트' 카테고리의 다른 글

[백준] 12865 - 평범한 배낭  (0) 2026.03.18
[백준] 9251 - LCS  (0) 2026.03.17
[백준] 2565 - 전깃줄  (0) 2026.03.16
[백준] 2156번 - 포도주 시식  (0) 2026.03.12
[백준] 10844번 - 쉬운 계단 수  (0) 2026.03.11