알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][13398] 연속합 2

kim.svadoz 2021. 5. 4. 22:01
반응형

www.acmicpc.net/problem/13398

 

13398번: 연속합 2

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 512 MB 9734 2781 2013 28.939%

문제

n개의 정수로 이루어진 임의의 수열이 주어진다. 우리는 이 중 연속된 몇 개의 수를 선택해서 구할 수 있는 합 중 가장 큰 합을 구하려고 한다. 단, 수는 한 개 이상 선택해야 한다. 또, 수열에서 수를 하나 제거할 수 있다. (제거하지 않아도 된다)

예를 들어서 10, -4, 3, 1, 5, 6, -35, 12, 21, -1 이라는 수열이 주어졌다고 하자. 여기서 수를 제거하지 않았을 때의 정답은 12+21인 33이 정답이 된다.

만약, -35를 제거한다면, 수열은 10, -4, 3, 1, 5, 6, 12, 21, -1이 되고, 여기서 정답은 10-4+3+1+5+6+12+21인 54가 된다.

입력

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

출력

첫째 줄에 답을 출력한다.

예제 입력 1

10
10 -4 3 1 5 6 -35 12 21 -1

예제 출력 1

54

코드

/*
    연속합 2.
    2차원 dp + 구간합
*/
import java.io.*;
import java.util.*;

public class p13398 {
    static int n;
    static int[] arr;
    static int[][] dp;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(br.readLine());
        arr = new int[n];
        StringTokenizer st =  new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        dp = new int[n][2]; // j = 0 : 수를 제거하지 않음, j = 1 : 특정 수를 제거함
        dp[0][0] = dp[0][1] = arr[0];

        int ans = arr[0];

        for (int i = 1; i < n; i++) {
            // 특정 수를 제거하지 않았을 경우에는 원래 방식대로 최대 연속합을 구한다.
            dp[i][0] = Math.max(arr[i], dp[i - 1][0] + arr[i]);

            // 특정 수를 제거할 경우는 2가지 케이스를 고려해야 한다.
            // 1. i번째 수가 처음 제거된 경우
            //   -> 단순히 이전 최대 연속 합을 할당하면 된다.
            // 2. i번째 수 전에 지워진 수가 있는 경우
            //   -> 현재 수는 지울 수 없으므로 이전 최대 연속합에다가 arr[i]를 더한다.
            dp[i][1] = Math.max(dp[i - 1][0], dp[i - 1][1] + arr[i]);

            ans = Math.max(ans, Math.max(dp[i][0], dp[i][1]));
        }
        System.out.println(ans);
    }
}
반응형