자료구조와 알고리즘
[백준/12015/C++] 가장 긴 증가하는 부분 수열 2
소 정
2022. 11. 9. 00:09
728x90
가장 긴 증가하는 부분 수열 2
문제 )
입출력 )
예제 입력 )
풀이 )
이분탐색 O(n log n)
입력받은 수열을 보면
10 20 10 30 20 50
증가하는 수열이므로 말 그대로 차례대로 증가하는 수의 갯수를 의미한다.
이렇게 총 길이가 4가 나온다.
이 문제의 시간은 1초로 이분탐색의 시간복잡도는 O(log n)으로 이분탐색을 이용하여 풀면 시간초과가 뜨지 않는다.
(나는 STL에 Lower_Bound & Upper_bound를 사용할 것이다.)
알고리즘 로직 )
수열을 차례로 입력받을 때 앞의 수와 비교하여
크다면? 벡터에 Push하고 Num++ 해준다.
작다면? lower_bound를 찾고 그 자리에 입력받은 수를 넣어준다.
=> 삽입되는 수보다 크거나 같은 첫번째 원소의 위치를 반환
코드 )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> v;
int n, num;
int main()
{
ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
v.push_back(-1);
cin >> n;
for (int i = 0; i < n; i++)
{
int input;
cin >> input;
if (input > v.back())
{
v.push_back(input);
num++;
}
else
{
vector<int>::iterator low = lower_bound(v.begin(), v.end(), input);
*low = input;
}
}
cout << num;
}
코드 설명
lower_bound와 upper_bound는 이진탐색트리를 기반으로 되어있다.
(이진탐색은 기본적으로 정렬이 되어있어야한다.)
#include<algorithm> 헤더를 추가해주어야 사용할 수 있다.
1. 수열 값을 하나씩 입력받는다.
2-1. 입력받은 값이 벡터의 끝보다 큰 경우
=> 벡터에 삽입 + num++
if (input > v.back()) {
v.push_back(input);
num++;
}
2-2. 입력받은 값이 벡터의 끝보다 크지 않은 경우
=> lower_bound로 입력받은 값보다 큰 곳이 배열 몇번째에 있는지 알아보기
else {
vector<int>::iterator low = lower_bound(v.begin(), v.end(), input);
*low = input;
}
728x90