주어진 배열에서 ai = a1 + (i-1)을 만족하는 부분 수열 a의 길이의 최댓값을 구하는 문제
--------------------------------------------------------------------------------------------------------------------------------------------------
그런데 가장 긴 증가하는 부분 수열을 찾는거니까 O(N^2)인가?
근데 N이 10만인데?
그러면 O(N)에 찾을 수 있다는건가?
한참 고민했다..
갑자기 번뜩이는?아이디어가 떠올랐다
먼저 핵심은 ai = a1 + (i-1)을 만족하는 수열은 무엇을 의미하는가?
a1 = 1이면 a2 = 2, a3 = 3,....
a1 = 2이면 a2 = 3, a3 = 4,...
a1 = 3이면 a2 = 4, a3 = 5,....
이렇게 1씩 증가하는 수열을 의미한다.
dp[i] = 마지막 원소가 i인 부분 수열의 길이의 최댓값
dp[i]를 모두 0으로 초기화 해두고, dp[A[0]] = 1로 초기화하면
그러면 부분 수열이 1씩 증가하는 수열이므로, 배열 A를 순회하면서.. dp[A[i]] = dp[A[i]-1] + 1이면 된다.
이때, A[i]-1이 A에 존재하지 않는다면 dp[A[i]] = 1로 자연스럽게 된다
[1,2,3,4,5,6]에서 dp[1] = 1, dp[2] = dp[1] + 1, dp[3] = dp[2] + 1,...
근데 만약에 [1,2,4,5]라고 해보자. dp[1] = 1, dp[2] = dp[1] + 1 = 2인데
dp[4] = ?
dp[3] + 1인데 지금 dp[3] = 0이므로 dp[4] = 1로 맞게 계산된다는 것을 알 수 있다
배열 A의 원소는 10^6까지니까 배열 dp의 크기는 10^6으로 초기화해두면 적절
n = int(input())
A = list(map(int,input().split()))
dp = [0]*(10**6+1)
dp[A[0]] = 1
for i in range(1,n):
dp[A[i]] = dp[A[i]-1] + 1
print(max(dp))
'알고리즘 > 다이나믹 프로그래밍' 카테고리의 다른 글
한번 쉬면 끝까지 쉬어야할 때 최대한 멀리 달리는 다이나믹 프로그래밍 (0) | 2025.03.19 |
---|---|
길이가 K인 증가하는 부분 수열의 개수를 구하는 다이나믹 프로그래밍 (0) | 2025.03.11 |
두 팀중 적어도 한 팀이 소수만큼 점수를 얻을 확률 (0) | 2025.03.02 |
구간의 시작과 끝중 하나를 선택할 수 있는 다이나믹 프로그래밍 (0) | 2025.02.26 |
배열의 모든 수의 관계가 약수 배수 관계가 되도록 만드는 다이나믹 프로그래밍 (0) | 2025.02.24 |