최장증가수열(LIS)란 ?
어떤 임의의 수열이 주어졌을때, 이 수열에서 몇 개의 수들을 제거해서 부분수열을 만들 수 있다.
이 때 만들어진 부분수열 중 오름차순으로 정렬된 가장 긴 수열을 최장증가수열이라고 한다.
동적계획법으로 풀 수 있는 알고리즘 중 하나
예시
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열
예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에
가장 긴 증가하는 부분 수열은 A = {**10**, **20**, 10, **30**, 20, **50**} 이고, 길이는 4이다.
방법
수열이 들어있는 배열 : array
인덱스마다 각 증가 수열의 길이 배열 : dp
Step 1. 2중포문 j : i를 기준으로 인덱스 0에서부터 i-1까지 체크한다.
Step 2. if (array[i] > array[j] && dp[j] + 1 > dp[i]) 을 통해 증가수열을 확인한다.
Step 3. dp[i] = dp[j] + 1 을 통해 증가수열을 연산
소스 코드
package 개념;
import java.util.Scanner;
public class LIS {
/*
*
* 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열
* 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에
* 가장 긴 증가하는 부분 수열은 A = {**10**, **20**, 10, **30**, 20, **50**} 이고, 길이는 4이다.
*
* */
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] array = new int[N]; // 인덱스마다 각 입력값
int[] dp = new int[N]; // 인덱스마다 각 증가 수열의 길이
int max = 0;
dp[0] = 1;
for(int i=1;i<N;i++) {
dp[i] = 1;
// i 를 기준으로 인덱스 0 에서부터 i-1까지 체크한다
// 길이를 기준
for(int j=0;j<i;j++) {
if (array[i] > array[j] && dp[j] + 1 > dp[i]) {
// 증가 수열
dp[i] = dp[j] + 1;
}
}
if (max < dp[i]) {
max = dp[i];
}
}
}
}
'알고리즘 > 개념' 카테고리의 다른 글
[JAVA] Union-Find (0) | 2021.02.02 |
---|---|
[JAVA] 이진탐색(Binary Search) (0) | 2020.09.22 |
[JAVA] 부분집합(SubSet) 구현 - 비트마스크 (0) | 2020.08.20 |
[JAVA]플로이드-와샬(Floyd-Warshall) 알고리즘 (0) | 2020.08.13 |
[JAVA]다음 순열(NextPermutation) (0) | 2020.08.12 |