728x90
11054번: 가장 긴 바이토닉 부분 수열
첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)
www.acmicpc.net
📄 문제개요
- 연속된 가장 긴 바이토닉 수열을 구하는 문제이다.
🤔 문제분석
- 다이나믹 프로그래밍 문제로, 현재 인덱스로부터 증가하는 가장 긴 값을 갱신한다.
- 처음부터 끝까지 순회하면서, 현재 인덱스로부터 가장 증가하는 긴 값을 dp 배열에 넣는다.
- 뒤집어서 한번더 증가하닌 긴 값을 dp 배열에 넣는다.
📝 의사코드
- 수열을 순회하면서, 증가하는 수열의 정보를 갱신한다.
- 수열을 반대로 뒤집어, 증가하는 수열의 정보를 갱신한다.
- 2개의 dp 테이블 ( Increase, Decrease ) 배열을 확인해, 조합하여 가장 큰 바이토닉 수열을 찾는다.
💻 코드
import sys
input = sys.stdin.readline
N = int(input())
A = list(map(int, input().split()))
# 증가하는 부분 수열의 길이 계산
increase = [1 for _ in range(N)]
for i in range(N):
for j in range(i):
if A[j] < A[i]:
increase[i] = max(increase[i], increase[j] + 1)
# 감소하는 부분 수열의 길이 계산
decrease = [1 for _ in range(N)]
A = A[::-1]
for i in range(N):
for j in range(i):
if A[j] < A[i]:
decrease[i] = max(decrease[i], decrease[j] + 1)
# 바이토닉 수열의 최대 길이 계산
max_length = 0
for i in range(N):
max_length = max(max_length, increase[i] + decrease[N-i-1] - 1)
# 결과 출력
print(max_length)
🎯 피드백 및 개선사항
- 처음에는 dp[start][end]로 2차원 배열로 문제를 접근하였다.
- dp[start][end] = max(dp[start][end-1], dp[start+1][end])로 접근 하였으며, 해당 문제는 연속된 부분수열이라는 조건을 만족 시키지 못한다.
- 위의 문제는 O(N^2)의 시간복잡도로 문제를 해결한다.
- 이분탐색을 통하여 O(Nlog(N)) 으로 시간복잡도를 줄일 수 있다.
- 바이토닉 수열의 정보를 저장하는 임시 배열을 두어, 만약 순회하면서 클경우 뒤에 이어 붙힌다.
- 만약 작다면, 이분탐색으로 해당 인덱스에 자기자신의 값을 갱신함으로서, 그 다음 계산때 항상 최대 값을 갱신하도록 한다.
import sys
from bisect import bisect_left
input = sys.stdin.readline
N = int(input())
A = list(map(int, input().split()))
dpr = [1 for _ in range(N)]
dpl = [1 for _ in range(N)]
dpr[0] = 1
dpl[0] = 1
r = [A[0]]
for i in range(1, N):
if A[i] > r[-1]:
r.append(A[i])
else:
idx = bisect_left(r, A[i])
r[idx] = A[i]
dpr[i] = len(r)
A = A[::-1]
l = [A[0]]
for i in range(1, N):
if A[i] > l[-1]:
l.append(A[i])
else:
idx = bisect_left(l, A[i])
l[idx] = A[i]
dpl[i] = len(l)
ans = 1
for i in range(N):
ans = max(ans, dpr[i] + dpl[N-1-i] - 1)
print(ans)
❓다른사람은 어떻게 풀었을까?
- 비슷한 조건으로 문제를 해결 하였습니다.
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 19238번 : 스타트 택시 (1) | 2023.12.29 |
---|---|
[백준] 16235번 : 나무 재테크 (1) | 2023.12.20 |
[백준] 17472번 : 다리만들기 2 (1) | 2023.12.06 |
[백준] 1035번 : 조각움직이기 (1) | 2023.12.05 |
[백준] 1759번 : 암호만들기 (1) | 2023.12.04 |