여기서 포스팅할 알고리즘은 lower bound를 이용한 O(nlog(n)) 알고리즘이다.
Lower Bound와 Upper Bound는 헤더파일 <algorithm>에 구현되어 있다.std::lower_bound( [배열의 처음 값의 주소], [배열의 끝 값의 주소], 찾고자 하는 값(k), [정렬])std::upper_bound( [배열의 처음 값의 주소], [배열의 끝 값의 주소], 찾고자 하는 값(k), [정렬])
[정렬] 에 아무것도 입력하지 않았을 경우 배열이 오름차순으로 정렬되어 있다고 가정하고 연산을 진행한다.반환 값으로 bound에 해당하는 주소값이 반환되므로, 함숫값에서 배열의 처음 값의 주소를 빼 줘야 몇 번째 인덱스인지 알 수 있다.
코드를 먼저 보고 예제를 넣어 설명을 하도록하겠다.
#include <cstdio>
#include <algorithm>
using namespace std;
int arr[1001],dp[1001];
int main(){
int N, size = 1;
int lower;
scanf("%d", &N);
for (int n = 1; n <= N; n++)
scanf("%d", &arr[n]);
dp[1] = arr[1];
for (int n = 2; n <= N; n++){
if (dp[size] < arr[n]){
size++;
dp[size] = arr[n];
}
else{
lower = lower_bound(dp + 1, dp + size + 1, arr[n]) - dp;
dp[lower] = arr[n];
}
for (int s = 1; s <= size; s++)
printf("%d,", dp[s]);
printf("\n");
}
printf("%d\n", size);
return 0;
}
만약 입력을 5개의 수 {1, 5, 3, 2, 4}를 넣어 본다고 가정해보자.
n == 1 : dp[1]에는 먼저 배열의 처음값인 1이 들어갈 것이다. dp배열 : {1}
n == 2 : dp[2]에는 dp[1] < 5 이기 때문에 5가 들어간다. dp배열 : {1,5}
n == 3 : dp[3]에는 dp[2] > 3 이므로 lower bound를이용하여 dp내부에
3이 있는지 확인한다. 없지만 1보다 크기때문에 index == 2이므로 3이 들어간다.
dp배열 : {1,3}
n == 4 : 마찬가지 방법으로 2가 index == 2에 들어간다. dp배열 : {1,2}
n == 5 : dp[4] < arr[5] 이므로 size가 증가하고 4가 들어간다. dp배열 : {1,2,4}
<dp 배열에 들어가는 숫자는 LIS와 무관하다.>
단지 dp 배열의 크기가 LIS인것 이다.
해당 LIS는 {1, 3, 4}뿐이지만 최종 dp배열에는 {1, 2, 4}가 들어간다.
| cs |
댓글 없음:
댓글 쓰기