티스토리 뷰
반응형
🔷 백준 11053번 – 가장 긴 증가하는 부분 수열 (Python)
문제설명
문제
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열(LIS: Longest Increasing Subsequence)의 길이를 구하는 문제입니다. 부분 수열이란 원소를 연속적이지 않게 선택해도 되지만, 순서는 반드시 유지해야 합니다. 증가하는 부분 수열이란 앞에 있는 원소보다 뒤의 원소가 더 큰 경우만 연결되는 수열을 말합니다.테스트케이스
입력
6
10 20 10 30 20 50
출력
4
문제 구체적 설명 (예시 기반)
입력 수열:10 20 10 30 20 50
가능한 증가 부분 수열 예:
10 20 30 50
→ 길이 4 ✅ (정답)10 20 50
→ 길이 310 30 50
→ 길이 320 30 50
→ 길이 310 20 30
→ 길이 3
10 20 30 50
이 최장인가?
- 10 → 20 (증가)
- 20 → 30 (증가)
- 30 → 50 (증가)
- 길이 4로 다른 어떤 증가 부분 수열보다 길이가 깁니다.
아이디어
1. 문제의 목적과 접근법
이 문제는 동적계획법이라는 방법을 사용해서 해결합니다. 동적계획법이란, 전체 문제를 작은 문제로 나누고 그 작은 문제들을 하나씩 해결해서 결과를 저장한 후, 이를 바탕으로 최종 답을 구하는 방법입니다.주어진 수열은 다음과 같습니다.
{10 20 10 30 20 50}
이 수열 중에서 증가하는 부분 수열의 길이를 찾는 문제입니다.
이때 증가하는 수열이란 숫자가 앞에서 뒤로 갈 때 항상 커져야 하는 수열을 말합니다. 숫자가 같거나 작아지면 증가하는 수열이 아닙니다.
2. 증가하는 수열과 증가하지 않는 수열의 예시
이 수열에서 증가하는 경우와 증가하지 않는 경우를 명확하게 구분해 보겠습니다.증가하는 수열인 경우의 예시
{20, 10}
→ 20 > 10이므로 증가하지 않습니다.{10, 10}
→ 10 = 10이므로 증가하지 않습니다.{30, 20}
→ 30 > 20이므로 증가하지 않습니다.{20, 20}
→ 20 = 20이므로 증가하지 않습니다.
문제 풀이 과정
시작하기 전에 dp 배열의 의미 설명하기
이제 문제를 풀 때는 dp라는 배열을 사용해서 해결합니다.- dp 배열의 각 값은 그 위치에서 끝나는 가장 긴 증가하는 수열의 길이를 나타냅니다.
- 처음에는 모두 자기 자신 하나로 이루어진 길이 1인 수열을 갖고 있다고 생각합니다. 따라서 모든 dp값을 1로 초기화합니다.
dp = {1, 1, 1, 1, 1, 1}
배열을 단계별로 추적하기 (반복, 중복 허용)
처음 원소는 10입니다.맨 처음에 있는 숫자 10은 그 앞에 아무 것도 없기 때문에, 길이 1짜리 수열입니다. 그래서 dp값은 처음 초기값 그대로 1입니다.
두 번째 원소 20을 봅니다.
{ 10 [20] 10 30 20 50 }
{ 1 1 1 1 1 1 }
↑
- 이제 20을 가지고 수열을 만드려면 앞에 있는 10보다 커야 합니다.
- 여기서 20은 10보다 크므로, 10과 20으로 이루어진
{10, 20}
은 증가하는 수열이 됩니다.
{ 10 [20] 10 30 20 50 }
{ 1 2 1 1 1 1 }
↑
여기까지 보면, {10, 20}
이라는 길이 2의 증가 수열이 만들어졌습니다.
세 번째 원소 10을 봅니다.
{ 10 20 [10] 30 20 50 }
{ 1 2 1 1 1 1 }
↑
이제 새로운 숫자 10을 확인합니다.
- 앞의 숫자 10과 같습니다. 숫자가 같으면 증가하지 않습니다.
{10,10}
은 증가하지 않습니다. - 10은 그 앞의 20보다 작으므로
{20, 10}
역시 증가하지 않습니다.
{ 10 20 [10] 30 20 50 }
{ 1 2 1 1 1 1 }
↑
- 10은 앞의 숫자들과 비교했을 때 증가하는 관계를 전혀 이루지 못했기 때문에 dp값은 여전히 1로 유지됩니다. (자기 혼자만 수열)
네 번째 원소 30을 봅니다.
{ 10 20 10 [30] 20 50 }
{ 1 2 1 3 1 1 }
↑
- 30은 앞의 첫 번째 숫자 10보다 크므로
{10, 30}
이라는 증가수열을 만들 수 있습니다. → 증가 - 30은 앞의 두 번째 숫자 20보다 크므로
{10, 20, 30}
도 가능합니다. → 증가 - 30은 앞의 세 번째 숫자 10보다 크므로
{10, 30}
가능 → 증가
- 첫 번째 10의 dp값은 1, 여기에 30이 붙으면 2입니다. (현재 dp=2)
- 두 번째 20의 dp값은 2, 여기에 30을 붙이면 길이가 3이 됩니다. (현재 dp=3)
- 세 번째 10의 dp값은 1, 붙이면 길이 2라서 더 커지지 않습니다.
{ 10 20 10 [30] 20 50 }
{ 1 2 1 3 1 1 }
↑
현재까지 가장 긴 증가 수열은 {10, 20, 30}
으로 길이 3입니다.
이런 식으로, 앞에서부터 하나하나 반복해서 비교하고, 배열을 중복해서 보여드립니다. 이 방식을 끝까지 반복하면 최종적으로 dp 배열에 저장된 값이 최장 증가 수열의 길이가 됩니다.
이런 식으로 전체 배열의 끝까지 똑같이 할 수 있습니다.
배열의 마지막까지 위에서 본 방식과 동일하게 각 숫자별로 앞의 모든 숫자와 비교하고,- 증가하면 앞의 dp값에서 +1을 해줍니다.
- 증가하지 않으면 dp값을 업데이트하지 않습니다.
- 최종 dp 배열은
{1, 2, 1, 3, 2, 4}
가 됩니다. - 이 중 가장 큰 값이 최장 증가 부분 수열의 길이입니다.
- 여기서는 최종적으로
4
가 답입니다.{10, 20, 30, 50}
수열입니다.
전체코드
N=int(input())
arr=list(map(int,input().split()))
dp = [1 for _ in range(N)]
for i in range(1,N):
max_k=0
for j in range(i-1,-1,-1):
if arr[i]>arr[j] and dp[j]>max_k:
max_k=dp[j]
dp[i]=max_k+1
print(max(dp))
개별코드 설명
1. 입력 & 초기화
dp = [1 for _ in range(N)]
모든 원소는 자기 자신만으로도 길이가 1인 LIS를 형성합니다.
2. 중첩 반복문
for i in range(1,N):
max_k=0
for j in range(i-1,-1,-1):
if arr[i]>arr[j] and dp[j]>max_k:
max_k=dp[j]
dp[i]=max_k+1
- i번째 원소를 끝으로 하는 LIS를 찾기 위해 i 이전의 모든 j를 역순으로 확인합니다.
arr[i] > arr[j]
이고dp[j]
가 현재max_k
보다 크면,max_k
를dp[j]
로 갱신합니다.dp[i]
는max_k + 1
로 설정하여, 현재 원소를 포함하는 가장 긴 증가 부분 수열의 길이를 저장합니다.
3. 최대 길이 출력
print(max(dp))
전체 dp 배열 중 최댓값이 LIS 길이입니다.
결론
- 이 문제는 전형적인 O(N²) DP로 해결할 수 있습니다.
- 핵심은 "이전 원소 중
arr[j] < arr[i]
인 경우의dp[j] + 1
중 최댓값"을 찾는 것입니다. - N이 최대 1000이므로 N²(100만) 연산은 충분히 1초 안에 동작합니다.
반응형
'백준 스터디' 카테고리의 다른 글
백준 1759번 – 암호 만들기 (Python) (3) | 2025.07.31 |
---|---|
백준 1759번 암호 만들기 C++ (2) | 2025.07.31 |
백준 11053번 – 가장 긴 증가하는 부분 수열 (C++) (1) | 2025.07.31 |
백준 2156번 포도주 시식 Python (3) | 2025.07.30 |
포도주 시식 백준 2156번 C++ (0) | 2025.07.30 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 알고리즘문제풀이
- 코딩 테스트
- 코딩
- 동적계획법
- 프로그래밍
- 알고리즘
- 문자열처리
- 코딩테스트
- 브루트포스
- 알고리즘 문제풀이
- C++ 알고리즘
- 파이썬
- python 알고리즘
- 객체지향
- C++
- 백준
- 그래프 탐색
- 그리디
- 문제 풀이
- Python
- DP
- 알고리즘기초
- 파이썬코딩
- c언어
- 인접 행렬
- 동적 계획법
- c++알고리즘
- dfs
- 문제풀이
- 그리디알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
글 보관함
반응형