일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- VS ERROR
- c
- Tips강좌
- 알고리즘
- Kotlin
- 문법
- 백준
- Javascript
- 연산자
- Desktop
- Win32
- 배열
- Tips프로그래밍강좌
- tipssoft
- 프로그래밍
- Direct2D
- 이지스퍼블리싱
- doit코틀린프로그래밍
- 김성엽
- c++
- 리뷰
- CS
- 티스토리
- c#
- Windows
- Programming
- Visual Studio
- 포인터
- 지식나눔강좌
- 함수
Archives
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
BAEKJOON 11053:가장 긴 증가하는 부분 수열 O(nLogn) for C++(DP) 본문
반응형
LIS를 해결하는 시간 복잡도 O(nLogn)의 알고리즘
코드
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int* input, * dp;
input = new int[n];
dp = new int[n + 1]{};
for (int i = 0; i < n; ++i)cin >> input[i];
int maxLength = 1;
for (int i = 0; i < n; ++i) {
if (dp[maxLength - 1] < input[i]) {
dp[maxLength++] = input[i];
}
else {
int left, right;
left = 1;
right = maxLength - 1;
while (left < right) {
if (dp[(left + right) >> 1] < input[i]) {
left = ((left + right) >> 1) + 1;
}
else {
right = ((left + right) >> 1);
}
}
dp[left] = input[i];
}
/*
for (int i = 0; i < maxLength; ++i) {
cout << dp[i] << " ";
}
cout << "\n";
*/
}
cout << maxLength -1;
return 0;
}
설명
이 알고리즘의 핵심은 증가 수열 중 각 길이별 최대 값이 가장 작은 수를 찾는 것이라 볼 수 있겠다. 각 수열의 마지막 요소의 값이 작을 수록 더 긴 수열을 만들 확률이 높아진다. 또한, 마지막 요소의 값을 알고 있다면 굳이 그 이전의 값을 알 필요는 없다.
배열 dp에는 각 길이별 마지막 요소의 가장 작은 값을 저장하도록 코드가 구성되어 있다. 또한, dp[i]는 절대적으로 dp[i+1]보다 작을 수밖에 없다. 만일 dp[i]가 dp[i+1]보다 큰 값을 가지고 있다면 dp[i+1]은 이전 탐색 과정에서 dp[i]보다 큰 값을 발견했어야하나 발견되지 않았기 때문이라 볼 수 있다. dp[i+1]보다 큰 값이 있다면 dp[i+2]로 정해질 수 있으므로 길이가 1만큼 더 긴 증가 수열이 발견된 것으로 볼 수 있다.
함께 보기.
O(n²)로 해결하는 알고리즘
# index
728x90
반응형
'DEV > Algorithm' 카테고리의 다른 글
BAEKJOON 1912:연속합(DP) (0) | 2021.12.21 |
---|---|
BAEKJOON 1932:정수 삼각형(DP) (0) | 2021.12.21 |
BAEKJOON 11053:가장 긴 증가하는 부분 수열 O(n²) for C (0) | 2021.09.08 |
BAEKJOON 2579: 계단 오르기 for C (0) | 2021.09.07 |
정렬 part1. 선택 정렬 (3) | 2020.03.21 |
Comments