Open WonYong-Jang opened 5 years ago
백준 11055번 가장 큰 증가 부분 수열
https://www.acmicpc.net/problem/11055
7570번: 줄세우기 https://www.acmicpc.net/problem/2631
LIS 문제 모음 : https://github.com/hotehrud/acmicpc/tree/master/algorithm/lis
===> 처음 구간을 잡을때 [1,n+1] 로 잡을것!!!!!!!!!!!!!!!!! ex1) 1 3 5 7 7 / target : 7 일 때 ==> 4번째 인덱스 리턴 ex2) 1 2 3 5 7 9 11 15 / target : 6 일때 ==> 5번째 인덱스 리턴 ex3) 1 2 3 4 5 / target : 7 일때 ==> 6번째 인덱스 출력 ( n + 1 )
public static int lower_bound(int s, int e, int target)
{
int mid =0;
while( s < e)
{
mid = (s + e) / 2;
if(data[mid] < target) {
s = mid + 1;
}
else {
e = mid;
}
}
return e;
}
public static int upper_bound(int s, int e, int target)
{
int mid =0;
while( s < e)
{
mid = (s + e) / 2;
if(data[mid] <= target) {
s = mid + 1;
}
else {
e = mid;
}
}
return e;
}
N^2 방법
dp[i] = data[i] 를 마지막 원소로 하는 증가 부분 수열의 최장 길이
Lower Bound 를 이용한 방법 / nlogn
dp 는 길이가 x인 최장증가수열의 마지막 수의 최소값을 의미
ex ) 10, 20, 40, 30, 70, 50, 60
1) 처음값 10을 넣어줌 : 배열의 최대 배열 사이즈 1 2) 20 값은 배열 마지막 값인 10보다 크므로 배열 뒤에 추가 : 배열 사이즈 2 3) 40 추가 : 배열 사이즈 3 / (10, 20, 40) 4) 30 값은 배열의 마지막 값인 40보다 작으므로 lower_bound 를 이용하여 40자리에 30을 치환 / (10,20, 30) 5) 70 추가 : 배열 사이즈 4 ( 10, 20, 30, 70) 6) 50 값을 70과 치환 (10, 20, 30, 50) : 배열사이즈 4 7) 60 추가 : 배열 사이즈 5 (10, 20, 30, 50, 60)
고려해야 할 부분
lower_bound 방식 ( lis 요소들 추적 가능한 방법! )
위의 방식은 LIS 길이를 구하는 방식이지만 해당 길이의 요소를 알수없다. ( 주의 ) ans 라는 pair 배열을 새로 만들고 정의해야함
ans[].dx : 실제 그 값이 들어갈수 있는 위치
ans[].dy : 실제 해당하는 값
실제 lis 배열을 구하는 알고리즘을 보자 예를들면 다음과 같다. 1 6 2 5 7 3 5 6인 경우 ans배열에는 다음과 같이 들어간다. dx :: 0 1 1 2 3 2 3 4 dy :: 1 6 2 5 7 3 5 6
이 값을 dx를 기준으로 뒤에서 부터 조사해오면 dx가 4일때 (6) - > dx가 3일때 (5) -> dx가 2일때 (3) -> dx가 1일때 (2) -> dx가 0일때(1)이다.
이것을 스택에 담아 역출력하면 1,2,3,5,6이라는 실제 배열을 구할 수 있다.
lower_bound 란?
인덱스 트리를 이용한 방법 / nlogn
설명 : https://m.blog.naver.com/kks227/220791986409 (그림 확인)
주의 사항
중복된 값이 발생할 경우 ==> 중복되는 값들 중에서는 가장 큰 인덱스 부터 방문해야 함!!! ==> 정렬할때 값 기준 오름차순 / 같은 값있을 경우는 인덱스 기준 내림차순