개발새발 로그

Dynamic Programming -(최대 부분 증가 수열[LIS]) 본문

알고리즘

Dynamic Programming -(최대 부분 증가 수열[LIS])

이즈흐 2023. 6. 7. 08:58

동적 계획법 중 최대 부분 증가 수열(LIS)를 구하는 문제가 있다.

 

아래 예제를 살펴보자

 

 

최대 부분 증가수열

N개의 자연수로 이루어진 수열이 주어졌을 때, 그 중에서 가장 길게 증가하는(작은 수에서 큰 수로) 원소들의 집합을 찾는 프로그램을 작성하라. 예를 들어, 원소가 2, 7, 5, 8, 6, 4, 7, 12, 3 이면 가장 길게 증가하도록 원소들을 차례대로 뽑아내면 2, 5, 6, 7, 12를 뽑아내어 길이가 5인 최대 부분 증가수열을 만들 수  있다.

입력설명

첫째 줄은 입력되는 데이터의 수 N(1<=N<=1000, 자연수)를 의미하고,

둘째 줄은 N개의 입력데이터들이 주어진다.

출력설명

첫 번째 줄에 부분 증가수열의 최대 길이를 출력한다.

 

  • 입력예제 1

8

5 3 7 8 6 2 9 4

 

  • 출력 예제 1

4

 

 

이 문제는 동적계획법으로 풀어야한다.

먼저 dy라는 배열을 선언하고

dy[i]의 값은 주어진 수열 arr[i]의 값이 최대 부분 증가수열의 마지막값이 되었을 때 가능한 부분 증가수열의 갯수 중 최댓값을 뜻한다.

 

그러면 여기에서 동적계획법을 사용해야한다.

현재 5가 마지막 수열 부분이 되면 dy[1]은 1이된다.

그리고 3이 마지막 수열 부분이 되면 dy[2]는 1이 된다. 

이것을 구할 때 arr[i]와 arr[i-1]을 비교해서 만약 arr[i]>arr[i-1] 이면 dy[i-1]+dy[1]을 해주면 된다.

예를 들어보자.

지금 현재 위와 같은 그림으로 되어있다.

그럼 만약 dy[2]를 구하려고 할 때 어떻게 해야 할까?

arr[2]>arr[1]이 성사된다. 그리고 arr[2]>arr[0] 또한 성사된다.

이때 둘 중 수열의 길이가 더 큰 것과 arr[2]와 합쳐서 dy배열에 넣는다.

 

 

 

이제 코드를 작성해보자.

let arr=[5,3,7,8,6,2,9,4]
let dy=Array(arr.length).fill(0);
let answer=0;

let dy[0]=1; //어차피 무조건 1이니까 1로 초기화
for(var i=1;i<arr.length;i++){
	for(var j=i-1;j>=0;j--){
    	let max=0;
    	if(arr[i]>arr[j] && dy[j]>max){
        	max=dy[j];
        }
        dy[i]=max;
        answer=Math.max(answer,dy[i]);
    }
}
console.log(answer);

 

728x90
반응형
LIST

'알고리즘' 카테고리의 다른 글

Dynamic Programming(냅색 알고리즘-2)  (0) 2023.06.07
Dynamic Programming(냅색 알고리즘-1)  (0) 2023.06.07
이분탐색  (0) 2023.06.04
그리디 알고리즘 기초문제 풀이  (3) 2023.06.04
그리디 알고리즘  (0) 2023.06.04