문제에서 주어진 대로 바이토닉 부분 수열은 수열 A가 주어졌을 때 A[i]값을 기준으로 A[0]에서 A[i-1]중 증가하는 부분 수열이 존재하고, A[i+1]에서 A[N]중 감소하는 부분 수열이 존재하는 경우를 말한다.
'가장 긴 증가하는 부분 수열' 알고리즘과 '가장 긴 감소하는 부분 수열' 알고리즘을 적당히 조합해보면 답이 나온다.
주의 할 점은,
dp (가장 긴 증가하는 부분 수열의 갯수)와 rdp (가장 긴 감소하는 부분 수열의 갯수) 각각의 최댓값을 더해준 후 -1을 해주어야 한다.
같은 값이 2번 counting 되기 때문!
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int MAX = 1001;
int bitonic(const vector<int>& A, int k) {
int dp[MAX];
int rdp[MAX];
dp[0] = rdp[k-1]=1;
for (int i = 1; i <k; i++) {
dp[i] = 1;
for (int j = 0; j <i; j++) {
if (A[i] > A[j] && dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
}
}
for (int i = k - 2; i >= 0; i--) {
rdp[i] = 1;
for (int j = k - 1; j >i; j--) {
if (A[i] > A[j] && rdp[i] < rdp[j] + 1)
rdp[i] = rdp[j] + 1;
}
}
int result=0;
for (int i = 0; i < k; i++) {
result = max(result, (dp[i] + rdp[i]) - 1);
}
return result;
}
int main() {
int k;
cin >> k;
if (k > MAX)
exit(EXIT_FAILURE);
vector<int>A(k);
for (int i = 0; i < k; i++)
cin >> A[i];
cout << bitonic(A, k) << endl;
return 0;
}