문제
접근 방식
수열 {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 이 주어졌을 때 1, 100, 2, 60, 50 처럼
들쑥날쑥한 부분 수열이 아닌 1, 2, 50, 60 처럼 증가하는 부분 수열 중에서
합이 가장 큰 부분 수열을 구해야 하는 문제다.
우선 간단하게 생각해보면 이전 수보다 큰 값이 나올 때까지 모두 합해주면
특정 수로 끝나는 부분 수열의 합을 구할 수는 있다.
1로 끝나는 부분 수열은 {1} = 1
1 > 100 > 2 (이전 수인 100보다 작음)
== 100으로 끝나는 부분 수열은 {1, 100} = 101
2 > 50 > 60 > 3 (이전 수인 60보다 작음)
== 60으로 끝나는 부분 수열은 {2, 50, 60} = 112
위와 같이 특정 수로 끝나는 부분 수열의 값을 알 수 있지만
문제에서 요구하는 부분 수열과는 조금 다르다.
문제에서는 {1, 2, 50, 60} = 113 처럼 연속된 부분 수열이 아니라도
값이 증가하기만 한다면 부분 수열로 만들 수 있기 때문에
{1, 2, 50, 60} 과 같은 수열을 만들기 위해서는
{1}과 {2, 50, 60}을 합치면 된다는 것을 알 수 있다.
즉, 60으로 끝나는 부분 수열의 합은
60보다 작은 부분 수열의 합들을 더한 값이 된다.
풀이
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
int max = arr[0];
int[] dp = new int[n];
dp[0] = arr[0];
for (int i = 1; i < n; i++) {
dp[i] = arr[i];
for (int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
dp[i] = Math.max(dp[j] + arr[i], dp[i]);
}
}
max = Math.max(max, dp[i]);
}
System.out.println(max);
}
}
'Java > Algorithms' 카테고리의 다른 글
[백준] 14501번 : 퇴사 (1) | 2023.12.24 |
---|---|
[백준] 9461번 : 파도반 수열 (1) | 2023.12.23 |
[백준] 2193번 : 이친수 (0) | 2023.12.20 |
[백준] 12852번 : 1로 만들기 2 (0) | 2023.12.18 |
[백준] 11659번 : 구간 합 구하기 4 (0) | 2023.12.18 |