본문 바로가기
알고리즘/백준 BOJ

13398. 연속합2

by 꾸준하곰 2022. 8. 20.

1. 해결방법

  • Dynamic Programming
  • DP[n] : n번째 수를 포함했을 때 연속합의 최대합을 의미.
  • DP_left[n] : n번째 수를 포함했을 때 n 기준 왼쪽에 있는 연속합의 최대합을 의미.
  • DP_right[n] : n번째 수를 포함했을 때 n 기준 오른쪽에 있는 연속합의 최대합을 의미.

 

  • 문제의 조건에는 "수열에서 수를 하나 제거할 수 있다 (제거하지 않아도 된다)" 라고 하였기 때문에, n을 기준으로 왼쪽과 오른쪽에 있는 연속합을 더할 수 있다.
  • DP_left[n - 1] + DP_right[n + 1] 
  • 수를 제거하지 않았을 때의 연속합의 최대합과, 수를 하나 제거했을 때의 연속합의 최대합을 비교하면 된다.

2. Solution

#include <iostream>

#define MAX_ 100000 + 1
#define endl "\n"

typedef long long ll;

using namespace std;

int n;
int arr[MAX_];
ll DP_left[MAX_];
ll DP_right[MAX_];
ll answer;

ll MAX(ll A, ll B) {return A > B ? A : B;}

void Input()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> arr[i];
    }
}

void Initial()
{
    DP_left[1] = arr[1];
    DP_right[n] = arr[n];

    answer = DP_left[1];    // 연속된 수 중 가장 큰 값
}

void Solution()
{
    for(int i = 2; i <= n; i++)
    {
        DP_left[i] = MAX(DP_left[i - 1] + arr[i], arr[i]);
        answer = MAX(answer, DP_left[i]);
    }
    for(int i = n - 1; i >= 1; i --)
    {
        DP_right[i] = MAX(DP_right[i + 1] + arr[i], arr[i]);
    }

    for(int i = 2; i <= n - 1; i++)
    {
        answer = MAX(answer, DP_left[i - 1] + DP_right[i + 1]);
    }

    cout << answer << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    Input();
    Initial();
    Solution();

    return 0;
}

'알고리즘 > 백준 BOJ' 카테고리의 다른 글

11399. ATM  (0) 2023.01.29
2839. 설탕 배달  (0) 2023.01.29
2193. 이친수  (0) 2022.08.17
2156. 포도주 시식  (0) 2022.08.17
1463. 1로 만들기  (0) 2022.08.05

댓글