728x90
반응형
https://www.acmicpc.net/problem/12015
12015번: 가장 긴 증가하는 부분 수열 2
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)
www.acmicpc.net
* c++에서 이진 탐색으로 원소를 탐색하는 lower_bound와 upper_bound 함수를 제공한다.
Lower_Bound
- 찾으려는 key 값보다 같거나 큰 숫자가 배열 몇 번째에서 처음 등장하는지 찾을 때 사용
Upper_Bound
- 찾으려는 key 값을 초과하는 숫자가 배열 몇 번째에서 처음 등장하는지 찾을 때 사용
문제 접근법
- 수열 A에 대하여 가장 긴 증가하는 부분 수열의 길이는 0 ~ 수열 A의 원소의 개수 만큼 나온다.
- 즉, 수열 A = {10, 20, 30, 25, 27, 50} 이면 가장 긴 증가하는 부분 수열의 길이는 0 ~ 6 사이다.
풀이 코드 및 해설
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#define FastIO ios::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL);
/// <summary>
/// Gold2 가장 긴 증가하는 부분 수열 2 - 이분 탐색 알고리즘
/// lower_bound의 개념을 활용해 해결한다.
/// lower_bound는 이진 탐색으로 원소를 탐색하는데 찾으려는 key값보다 같거나 큰 숫자가 배열 몇 번째에서 처음 등장하는지 찾을 때 쓴다.
/// 먼저 sequence 벡터를 만들고, std::cin >> a를 통해 값을 입력 받는다.
/// 1) sequence.empty() || sequence.back() < a 면 sequence.push_back(a)를 통해 값을 넣는다.
/// 2) sequence에 값이 있는데 sequence.back() > a면 lower_bound를 통해 a값보다 작거나 같은 값이 어디에 있는지 꺼내오고 해당 위치의 값을 a로 바꾼다.
/// 2-1) lower_bound(sequence.begin(), sequence.end(), a) - sequence.begin();을 통해 index 값을 구한다.
///
/// ex) N = 6, A = {10, 20, 30, 25, 15, 60} 일 때, 가장 긴 중가하는 부분 수열을 찾는 방법은 다음과 같다.
/// 1) sequence = {10, 20, 30}인 상황에서 25가 들어오면
/// 2) sequence.back() = 30 > 25 이므로
/// 3) lower_bound를 통해 25보다 같거나 큰 숫자가 배열 몇 번 째에 처음 나오는지 반환후 빈 변수에 저장 ->int index = 2;
/// 4) sequence[index] = 25로 바꾸기.
/// </summary>
using namespace std;
vector<int> sequence;
int main(void)
{
FastIO;
int N = 0; //수열 A의 크기 N
std::cin >> N;
for(int i = 0; i < N; i++)
{
int a = 0;
std::cin >> a;
if(sequence.empty() || sequence.back() < a)
{
sequence.push_back(a);
}
else
{
int index = std::lower_bound(sequence.begin(), sequence.end(), a) - sequence.begin();
sequence[index] = a;
}
}
std::cout << sequence.size() << "\n";
return 0;
}
728x90
반응형
'알고리즘 (C++)' 카테고리의 다른 글
[피보나치 수열] 2가지 방법 (0) | 2023.11.14 |
---|---|
[백준] 2744번 대소문자 바꾸기 (0) | 2023.11.09 |
[백준] 이분 탐색 (0) | 2023.06.28 |
[백준] 분리집합(유니온-파인드) (0) | 2023.06.24 |
[백준] 다리 놓기 - DP (0) | 2022.11.12 |