
https://www.acmicpc.net/problem/11053

import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int max = 1;
int[] numbers = new int[N];
int[] length = new int[N];
st = new StringTokenizer(br.readLine());
for(int i=0 ; i<N ; i++) {
numbers[i] = Integer.parseInt(st.nextToken());
}
for (int i = 0; i < N; i++){
length[i] = 1;
for (int j = 0; j < i; j++){
if(numbers[j] < numbers[i]){
length[i] = Math.max(length[i], length[j] + 1);
}
}
max = Math.max(length[i], max);
}
bw.write(String.valueOf(max));
bw.flush();
bw.close();
}
}

위 수열에서 최장 증가 수열을 찾으면 아래와 같다

주어진 수열에서 LIS의 길이를 구하는 방법은 2가지이다

dp[i] : i번째 인덱스에서 끝나는 최장 증가 수열의 길이 로 정의한다void LIS_DP() {
for (int i = 0; i < n; i++) {
dp[i] = 1; // 자기 자신의 최장 증가 수열의 크기를 1로 설정
for (int j = 0; j < i; j++) {
//i번째 이전의 모든 원소에 대해, 그 원소에서 끝나는 LIS의 길이를 확인한다.
if (arr[i] > arr[j]) {
//단, 이는 현재 수가 그 원소보다 클 때만 확인한다.
dp[i] = max(dp[i], dp[j] + 1); //dp[j] + 1 : 이전 원소에서 끝나는 LIS에 현재 수를 붙인 새 LIS 길이
}
}
}
}









int binary_search(vector<int> lis, int start, int end, int element) {
//이분 탐색으로 lis 벡터 내에서 element의 위치를 반환
//lis 벡터의 start - end 구간에서만 확인
while (start < end) {
int mid = (start + end) / 2;
if (element > lis[mid]) start = mid + 1;
else end = mid;
}
return end;
}
int LIS_BS() {
int ret = 0;
vector<int> lis;
lis.push_back(arr[0]);
for (int i = 1; i < n; i++) {
//만약 lis 벡터의 마지막 수보다 i번째 수가 크다면, 그냥 뒤에 붙인다.
if (arr[i] > lis.back()) {
lis.push_back(arr[i]);
ret = lis.size() - 1;
}
//i번째 수에 대해, lis 벡터 내에서 그 수의 위치를 찾는다.
int pos = binary_search(lis, 0, ret, arr[i]);
lis[pos] = arr[i];
}
return ret + 1;
}