def find_lis(array):
dp = [0]*len(array)
for i in range(len(array)):
dp[i] = 1
for j in range(i+1):
if arr[i] > arr[j]:
dp[i] = max(dp[i],dp[j] + 1)
return dp
def find_lds(array):
dp = [0]*len(array)
for i in range(len(array)):
dp[i] = 1
for j in range(i+1):
if array[i] < array[j]:
dp[i] = max(dp[i],dp[j] + 1)
return dp
N = int(input())
arr = list(map(int,input().split()))
lis_dp = find_lis(arr)
result = 0
for ind in range(N):
lds_dp = find_lds(arr[ind:])
result = max(result,lis_dp[ind] + max(lds_dp) -1)
print(result)
처음에 푼 방식이다. 먼저 가장 긴 증가 부분 수열의 길이를 구하고 난뒤,
각 index마다 잘라서 가장 긴 감소 부분 수열을 구해서 더해주었다.
이러한 방식으로 푸니깐 시간이 오래걸렸다.
def find_lis(array):
dp = [0]*len(array)
for i in range(len(array)):
dp[i] = 1
for j in range(i+1):
if arr[i] > arr[j]:
dp[i] = max(dp[i],dp[j] + 1)
return dp
def find_lds(array):
dp = [0]*len(array)
for i in range(len(array)-1,-1,-1):
dp[i] = 1
for j in range(i+1,len(array)):
if array[i] > array[j]:
dp[i] = max(dp[i],dp[j] + 1)
return dp
N = int(input())
arr = list(map(int,input().split()))
lis_dp = find_lis(arr)
lds_dp = find_lds(arr)
result = 0
for ind in range(N):
result = max(result,lis_dp[ind]+lds_dp[ind]-1)
print(result)
그 다음으로 푼 방식이다.
LIS를 두군데로 해서 구해주었다.
앞에서 가장 긴 뒤에서 가장 긴 증가 부분수열을 구해주었다.
긴 바이토닉 부분 수열을 보면 가운데를 중심으로 좌측에서는 긴 증가부분 수열이고, 우측은 감소부분수열인데, 이걸 역으로 보면 우측을 거꾸로 돌리면 증가 부분 수열이 된다.
이러한 점을 이용해 좌측에서부터의 긴 증가부분 수열과 수열을 거꾸로 해서 긴 증가부분 수열의 길이를 구해, 서로 더해주면 긴 바이토닉 부분 수열이 나온다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 3020 개똥벌레 (0) | 2021.02.18 |
---|---|
[BOJ/백준] 6593 상범 빌딩 (0) | 2021.02.17 |
[BOJ/백준] 2631 줄세우기 (0) | 2021.02.16 |
[BOJ/백준] 2873 롤러코스터 (0) | 2021.02.16 |
[BOJ/백준] 1600 말이 되고픈 원숭이 (0) | 2021.02.16 |