PS/BOJ
BOJ 11054 가장 긴 바이토닉 부분 수열
모달조아
2021. 7. 6. 18:44
boj 11054 가장 긴 바이토닉 부분 수열
boj 11503 가장 긴 증가하는 부분 수열 문제를 풀었다면 쉽게 이해할 수 있는 문제이다. 아래의 풀이를 참고할 것을 추천한다.
boj 11503 가장 긴 증가하는 부분 수열 문제 풀이
바이토닉 수열이 기준이 되는 수를 중심으로 증가하는 수열에서 감소하는 수열로 바뀐다는 것에 포인트를 잡았다.
바이토닉 수열의 길이의 최댓값 = (기준 수까지 증가하는 수열 길이 + 기준 수부터 감소하는 수열 길이)의 최댓값라고 이해할 수 있다.
Dinc[i]는 i를 마지막 원소로하는 증가 수열 길이의 최댓값이고, Ddec[i]는 시작 원소를 i로 하는 감소 수열 길이의 최댓값이다. 쉽게 구현하기 위해 Ddec[i] 표현을 달리해보자. 수열이 담긴 배열 a[i]를 거꾸로 끝에서부터 탐색한다고 하면, Ddec[i]도 i를 마지막 원소로하는 증가 수열 길이의 최댓값이라고 정의할 수 있다. 문제에 주어진 예시를 바탕으로 그림으로 나타내보겠다.
Dsum[i] = Dinc[i] + Ddec[i] 이다. 기준 수의 길이가 두번 더해지므로 Dsum[i]에서 1을 빼줘야 문제에서 구하고자 하는 바이토닉 수열 길이의 최댓값이 된다. 위 내용을 바탕으로 구현한 코드를 보자.
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int a[1005];
int Dinc[1005];
int Ddec[1005];
int Dsum[2005];
int ans;
int main(void)
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++)
{
Dinc[i] = 1;
for (int j = 1; j < i; j++)
{
if (a[i] > a[j] && Dinc[j] >= Dinc[i])
Dinc[i] = Dinc[j] + 1;
}
}
for (int i = n; i >= 1; i--)
{
Ddec[i] = 1;
for (int j = n; j > i; j--)
{
if (a[i] > a[j] && Ddec[j] >= Ddec[i])
Ddec[i] = Ddec[j] + 1;
}
Dsum[i] = Dinc[i] + Ddec[i];
ans = max(ans, Dsum[i]);
}
cout << ans - 1;
}