문제
수열 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의 합이 가장 큰 증가 부분 수열의 합을 출력한다.
풀이
다이나믹 프로그래밍(dp)를 이용하여 풀이가 가능하다.
수열을 0부터 n까지 반복하면서 i번째 인덱스가 증가 부분 수열일 경우 그 합을 구한다.
다시 말해 dp[i] : i번째 인덱스의 증가 부분 수열의 합이다.
예를 들어 수열이 {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우 dp는 아래와 같다.
수열 | 1 | 100 | 2 | 50 | 60 | 3 | 5 | 6 | 7 | 8 |
dp | 1 | 101 | 3 | 53 | 113 | 6 | 11 | 17 | 25 | 33 |
소스 코드
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] sequence = new int[n];
for (int i = 0; i < n; i++) {
sequence[i] = scanner.nextInt();
}
// dp[n] : n번째 인덱스까지의 증가 부분 수열의 합
int[] dp = new int[n];
int result = 0; // 최대 dp 값
for (int i = 0; i < n; i++) {
dp[i] = sequence[i]; // 초기값 (i인덱스의 값이 0~(i-1)인덱스의 값보다 작은 경우)(가장 큰 증가 부분 수열이 자기 자신인 경우)
for (int j = 0; j < i; j++) {
if(sequence[j] < sequence[i]) {
dp[i] = Math.max(sequence[i] + dp[j], dp[i]);
}
}
// 최대 dp값 구하기
if(result < dp[i]) {
result = dp[i];
}
}
System.out.println(result);
}
}
문제 출처 : www.acmicpc.net/problem/11055
반응형
'공부 > 알고리즘' 카테고리의 다른 글
[백준] 2225번 합분해 (0) | 2021.01.02 |
---|---|
[백준] 2293번 동전 1 (0) | 2021.01.01 |
[백준] 11052번 카드 구매하기 (2) | 2020.12.20 |
[백준] 9095번 1,2,3 더하기 (0) | 2020.12.12 |
[백준] 4796번 캠핑 (0) | 2020.12.02 |