본문 바로가기
카테고리 없음

1912. 연속합

by 꾸준하곰 2022. 8. 8.

1. 시간 초과된 풀이

더보기

문제풀이 : 

1)  DP[] 배열에 choose 개의 연속된 수의 합을 저장했다. 그리고 N[] 배열에 입력받은 수열을 저장했다.

2) DP[] 배열은 choose 의 값에 따라 저장되는 값이 달라진다.

3) choose = 1 일 때의 DP[] 배열은 N[] 배열과 동일하다. DP[i] = N[i]

4) choose = 2 일 때의 DP[] 배열은 DP[i] = N[i] + N[i+1] 이다. 즉, DP[i] = (choose = 1 일 때의 DP[i]) + N[i+1]

5) choose = 3 일 때의 DP[] 배열은 DP[i] = N[i] + N[i+1] + N[i+2] 이다. 즉, DP[i] = (choose = 2 일 때의 DP[i]) + N[i+2]

6) 정리하자면, (choose = N 일 때의 DP[i]) = (choose = N-1 일 때의 DP[i]) + N[i + choose]

    예를들자면, choose = 2 일 때의 DP[] 와 choose = 3 일 때의 DP[] 를 비교해 보자

7) vscode 에서 예제대로 입력했을 때, 정답이 출력되었다. ☞즉, 백준 기준 제한시간(1초) 내에 계산되지 못한 것이다.

  choose = 2 choose = 3
i = 0 N[0] + N[1] N[0] + N[1] (= DP[0])+ N[2]
i = 1 N[1] + N[2] N[1] + N[2] (= DP[1])+ N[3]
i = 2 N[2] + N[3] N[2] + N[3] (= DP[2])+ N[4]
i = 3 N[3] + N[4]  

 

시간초과 이유:

백준에서 시간 초과된 이유를 고민해봤다.

1) n의 최대값인 100000의 경우를 생각해보면, 제한시간(1초) 내에 실행완료되지 않는다.

2) 빅오표기법으로 시간복잡도를 계산해봤다.

    내가 작성한 코드는 O(100000^2) 의 시간복잡도를 갖는다. 보통 n = 10000 일 때 O(n^2) 는 1초의 시간이 걸린다고 한다.     

3) 따라서, O(100000^2) 는 제한시간(1초) 내에 실행되지 않는다.

 

#include <iostream>
#include <cstring>
#include <algorithm>

#define MAX 100000
#define endl "\n"

using namespace std;

int n;
long long N[MAX];
long long DP[MAX];

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

void Initial()
{
    memset(DP, 0, sizeof(DP));
}

void Solution()
{
    long long sum = 0;
    long long maxSum = -2000;
    for(int choose = 1; choose <= n; choose++)
    {
        for (int i = 0; i <= n - choose; i++)
        {
            sum = DP[i] + N[i + choose - 1];


            DP[i] = sum;
            maxSum = max(maxSum, sum);
        }
    }

    cout << maxSum << endl;
}

int main()
{
    Input();
    Initial();
    Solution();

    return 0;
}

 

2. 해결방법

 

3. Solution

 

댓글