N
: 수열의 크기
A
: 주어진 수열
수열 전체에서 감소하는 숫자들을 찾아 만든 부분 수열 중 가장 긴 수열의 길이를 찾아 출력하는 문제이다.
⭐️ 감소하는 숫자 찾는 법
- 해당 수열로 만들 수 있는 부분 수열 중 감소하는 숫자들로 구성한 경우를 찾는다.
- 이전의 값들 중 현재 값보다 큰 경우가 있는지 확인하고 그 수를 센다.
- 최대 길이의 부분 수열 내에 있는 숫자들은 이전 숫자까지의 부분 수열 개수에 1을 더한 값을 수열의 길이로 갖는다.
위의 방법을 정리해보면 다음과 같다.
1️⃣ 각 요소를 접근하면서 현재 수가 이전보다 작은지 확인한다.
2️⃣ 현재보다 더 작은 요소가 몇 개인지 누적해서 센다.
개수를 누적해서 셀 수 있기 때문에 부분 수열의 길이를 dp 테이블 값에 채워주면서 마지막으로 최댓값을 출력하도록 구현한다.
이전 값까지의 최대 길이에 1을 증가시킨 값(﹦ 현재 값을 부분 수열에 넣었을 때의 수열 길이)을 dp 테이블에 넣어주면서 최댓값을 구해야 한다.
max()
함수를 이용해 조건에 맞을 때 개수를 늘려주면서 현재 값보다 큰 값을 테이블에 채울 수 있도록 한다.
DP 테이블 채우기 →
최종 시간복잡도
총 이 된다.
최악의 경우 이므로 이는 1초 내에 연산이 가능하다.
DP로 최대 길이 구하기
1️⃣ dp 테이블를 정의한다.
2️⃣ dp 테이블의 초기값 계산한다.
3️⃣ 조건에 따라 dp 테이블을 채워준다.
4️⃣ dp 테이블의 마지막 값을 출력한다.
# DP 테이블 초기화
dp = [0] * N
0
으로 값을 채웠는데 예제1의 출력이 1이 작은 값이 나왔다.1
로 초기화해주어야 했던 것이다.# dp 테이블 채우기
for i in range(1, N):
for j in range(i):
if A[j] > A[i]:
dp[i] = dp[j] + 1
틀렸습니다
가 나왔다.import sys
input = sys.stdin.readline
# N 입력
N = int(input())
# A 입력
A = list(map(int, input().split()))
# dp 테이블 초기화
dp = [0] * N
# dp 테이블 채우기
for i in range(1, N):
for j in range(i):
if A[j] > A[i]:
dp[i] = max(dp[i], dp[j] + 1)
# 결과 출력
print(max(dp))