boj-11055 가장 큰 증가 부분 수열(JavaScript)
문제
수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수열은 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 이고, 합은 113이다.
입력
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000)
출력
첫째 줄에 수열 A의 합이 가장 큰 증가 부분 수열의 합을 출력한다.
예제 입력 1
1 | 10 |
예제 출력 1
1 | 113 |
내 코드
1 | const [N, input] = require("fs") |
풀이
DP는 해당 인덱스까지 가장 긴 부분수열의 합을 나타낸다. 이를 계산하기 편하게 하기 위해 DP에 A 수열의 값을 spread 문법으로 복사해준다.
어짜피 DP[0]은 1로 확정이므로 i(인덱스)가 1부터 반복문을 순회한다.
이는 DP에 값을 저장하기 위한 반복문이다.i 이전까지 수열 값과 A[i]값을 비교하여 A[i]가 A[j]보다 크고 DP[i] 값이 DP[j]+A[i] 보다 작으면 증가하는 부분 수열에 포함될 수 있다.
그렇기 때문에 해당 DP[i]값을 새로운 값으로 갱신해준다.
예시
1 | const A = [1, 100, 2, 50, 60, 3, 5, 6, 7, 8]; |
1. i = 1 && j = 0
일 때
- A[1] = 100, A[0] = 1이므로 A[i] > A[j] 조건 만족한다
- DP[1] < DP[0] + A[1] 만족하므로 DP[1] = DP[0] + A[1]로 갱신
1 | DP = [1, 101, 2, 50, 60, 3, 5, 6, 7, 8]; |
2. i = 2 이고
2.1. j = 0 일 때
- A[2]=2, A[0] = 1 이므로 A[i] > A[j] 조건 만족한다.
- DP[2] < DP[0] + A[2] 만족하므로 DP[2] = DP[0] + A[2]로 갱신
2.2. j = 1 일 때,
- A[2]=2, A[1] = 100 이므로 A[i] > A[j] 조건 만족하지 못한다.
1 | DP = [1, 101, 3, 50, 60, 3, 5, 6, 7, 8]; |
즉, 0번째부터 해당 인덱스까지 수열의 두 수를 비교하고 DP에 저장된 값도 비교하여 둘다 만족하면 DP 값을 갱신하는 것이다.