728x90
반응형
문제:
수열 S가 어떤 수 Sk를 기준으로 S1 < S2 < ... Sk-1 < Sk > Sk+1 > ... SN-1 > SN을 만족한다면, 그 수열을 바이토닉 수열이라고 한다.
예를 들어, {10, 20, 30, 25, 20}과 {10, 20, 30, 40}, {50, 40, 25, 10} 은 바이토닉 수열이지만, {1, 2, 3, 2, 1, 2, 3, 2, 1}과 {10, 20, 30, 40, 20, 30} 은 바이토닉 수열이 아니다.
수열 A가 주어졌을 때, 그 수열의 부분 수열 중 바이토닉 수열이면서 가장 긴 수열의 길이를 구하는 프로그램을 작성하시오.
입력:
첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)
출력:
첫째 줄에 수열 A의 부분 수열 중에서 가장 긴 바이토닉 수열의 길이를 출력한다.
풀이방법:
두 개의 LIS(가장 긴 증가하는 부분 수열)을 사용해서 풀면 된다. 한 LIS는 앞에서부터, 다른 LIS는 뒤에서부터 수행한다. 수행하면서 각 위치까지의 LIS의 길이를 저장해둔다.
두 배열(dp, dp2)에 LIS의 길이를 저장했으므로 이 둘을 zip으로 같이 탐색하면서 합이 가장 큰 경우를 답으로 출력하도록 한다. 즉, 이 말은 기준이 Sk를 기준으로 왼쪽과 오른쪽의 길이의 합을 더하는 것과 같으며, Sk는 최종적으로 두 번 더해지기 때문에 -1을 뺀 값이 정답이 된다.
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
31
32
33
34
35
36
37
|
import bisect
n = int(input())
numbers = list(map(int,input().split()))
dp = []
seq = []
for i, n in enumerate(numbers):
if not len(seq):
seq.append(n)
else:
if seq[-1] < n:
seq.append(n)
else:
idx = bisect.bisect_left(seq,n)
seq[idx] = n
dp.append(len(seq))
dp2 = []
seq = []
numbers.reverse()
for i, n in enumerate(numbers):
if not len(seq):
seq.append(n)
else:
if seq[-1] < n:
seq.append(n)
else:
idx = bisect.bisect_left(seq,n)
seq[idx] = n
dp2.append(len(seq))
dp2.reverse()
answer = 0
for i,v in zip(dp,dp2):
answer = max(answer,i+v)
print(answer-1)
|
cs |
문제링크:
https://www.acmicpc.net/problem/11054
728x90
반응형
'Algorithm > Python' 카테고리의 다른 글
[BOJ]2638. 치즈 (0) | 2021.09.06 |
---|---|
[BOJ]2636. 치즈 (0) | 2021.09.03 |
[BOJ]2565. 전깃줄 (0) | 2021.09.01 |
[BOJ]2042. 구간 합 구하기 (0) | 2021.08.31 |
[BOJ]2573. 빙산 (0) | 2021.08.30 |