https://sskl660.tistory.com/89
[Java]최장 증가 부분 수열(LIS, Longest Increasing Subsequence)
*최장 증가 부분 수열(LIS, Longest Increasing Subsequence) ->최장 증가 부분 수열이란, 주어진 수열에서 오름차순으로 정렬된 가장 긴 부분 수열을 찾는 문제이다. 여기서 부분 수열은 연속적이거나,
sskl660.tistory.com
https://www.acmicpc.net/problem/11053
11053번: 가장 긴 증가하는 부분 수열
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
두 가지 방법이 있다.
1. 최장 증가 부분 수열의 길이만 구하는 방법 (이 수열의 원소는 알 수 없다)
2. 최장 증가 부분 수열 자체를 구하는 방법
물론 1이 2보다 빠르다
1은 이진 탐색을 사용해서 O(NlgN)
2는 O(N^2)
1번
import java.util.*;
import java.io.*;
public class s2_11053_lis{
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int[] dp, pp;
static int n;
public static void main(String[] args){
n = fs.nextInt();
dp = new int[n];
pp = new int[n];
for (int i=0;i<n;i++) pp[i] = fs.nextInt();
int len = 0;
for (int i=0;i<n;i++){
int index = BS(pp[i], 0, len, len + 1);
if (index == -1){
dp[len++] = pp[i];
}
else{
dp[index] = pp[i];
}
}
pw.println(len);
pw.close();
}
private static int BS(int num, int start, int end, int size) {
int res = 0;
while (start <= end){
int mid = (start + end) / 2;
if (num <= dp[mid]){
res = mid;
end = mid - 1;
}
else{
start = mid + 1;
}
}
if (start == size){
return -1;
}
else{
return res;
}
}
// ----------input function----------
static void sort(int[] a){
ArrayList<Integer> L = new ArrayList<>();
for (int i : a) L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++) a[i] = L.get(i);
}
static class FastScanner{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next(){
while (!st.hasMoreTokens()){
try{
st = new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt(){
return Integer.parseInt(next());
}
int[] readArray(int n){
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
long nextLong(){
return Long.parseLong(next());
}
}
}
2번
import java.util.*;
import java.io.*;
public class Main{
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int[] dp, pp;
static int ans = 1;
public static void main(String[] args){
int n = fs.nextInt();
dp = new int[n];
pp = new int[n];
for (int i=0;i<n;i++) pp[i] = fs.nextInt();
for (int i=0;i<n;i++) solve(i);
pw.println(ans);
pw.close();
}
static void solve(int ptr){
int max = 1;
for (int i=0;i<ptr;i++){
if (pp[i] < pp[ptr]){
max = Math.max(max, dp[i] + 1);
}
}
dp[ptr] = max;
ans = Math.max(ans, max);
}
// ----------input function----------
static void sort(int[] a){
ArrayList<Integer> L = new ArrayList<>();
for (int i : a) L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++) a[i] = L.get(i);
}
static class FastScanner{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next(){
while (!st.hasMoreTokens()){
try{
st = new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt(){
return Integer.parseInt(next());
}
int[] readArray(int n){
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
long nextLong(){
return Long.parseLong(next());
}
}
}
'PS > Algorithms' 카테고리의 다른 글
[Java] Fenwick Tree(Binary Indexed Tree, BIT) - O(lgN)의 부분합 계산 (0) | 2022.01.19 |
---|---|
[Java] Knapsack Problem - 배낭 문제(DP) (0) | 2022.01.19 |
[Java] LCS - 최장 공통 부분 수열 (0) | 2022.01.18 |
[Java] Floyd-Warshall algorithm - (그래프)모든 정점 간의 최단거리 (0) | 2022.01.08 |
[Java] Bellman-ford algorithm - (그래프)간선 가중치가 음수 (0) | 2022.01.08 |