https://www.acmicpc.net/problem/11054
11054번: 가장 긴 바이토닉 부분 수열
첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)
www.acmicpc.net
앞에서부터 가장 긴 부분수열 사이즈 찾아서 배열에 넣고,
뒤에서부터 사이즈 찾아서 넣고 더한 값 중에서 가장 큰 값을 찾았다.
중복값이 만날 때 발생하니까 하나 빼주기
생각해보니 dp가 아니라 이분탐색으로 풀었다. lower_bound 찾아서 했으니 흠 🧐
전체 코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int N, arr[1000], dp_bottomUp[1000], dp_topDown[1000];
vector<int> lis;
int main(int argc, const char * argv[]) {
cin >> N;
for (int i=0; i<N; i++) {
cin >> arr[i];
}
for (int i=0; i<N; i++) {
if (lis.empty()) {
lis.push_back(arr[i]);
}
else if (lis.back() < arr[i]) {
lis.push_back(arr[i]);
}
else {
int idx = (int)(lower_bound(lis.begin(), lis.end(), arr[i]) - lis.begin());
lis[idx] = arr[i];
}
dp_bottomUp[i] = (int)lis.size();
}
lis.clear();
for (int i=N-1; i>=0; i--) {
if (lis.empty()) {
lis.push_back(arr[i]);
}
else if (lis.back() < arr[i]) {
lis.push_back(arr[i]);
}
else {
int idx = (int)(lower_bound(lis.begin(), lis.end(), arr[i]) - lis.begin());
lis[idx] = arr[i];
}
dp_topDown[i] = (int)lis.size();
}
vector<int> res;
for (int i=0; i<N; i++) {
res.push_back(dp_bottomUp[i] + dp_topDown[i]);
}
sort(res.begin(), res.end());
cout << res.back()-1 << "\n";
return 0;
}
'ALGORITHM > OTHER' 카테고리의 다른 글
[c++] 11723 집합 (비트마스크) (0) | 2021.02.13 |
---|---|
[c++] 1655 가운데를 말해요 (힙!) (2) | 2021.02.08 |
[c++] 2805 나무 자르기 (이분탐색) (0) | 2021.01.29 |
[c++] 1654 랜선 자르기 (파라메트릭 서치(Parametric Search)) (0) | 2021.01.28 |
[c++] 14425 문자열 집합 - Trie (트라이), set, unordered_set (0) | 2021.01.24 |