고인물을 지양하는 블로그

BOJ 1912 연속합 본문

Algorithms/ACMICPC(백준)

BOJ 1912 연속합

yunjaeGong 2019. 7. 17. 16:39

https://www.acmicpc.net/problem/1912

 

1912번: 연속합

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

www.acmicpc.net

첫 번째 풀이

#include <cstdio>

int main() {
    int n;
    scanf("%d",&n);
    int  sum[n], max;
    
    for(int i=0;i<n;++i) {
        scanf("%d",&sum[i]);
        if(i>0)
            sum[i] += sum[i-1];
    }
    max = sum[0];
    
    for(int i=1;i<n;++i)
        for(int j=0;j<i;++j)
            if(max < sum[i]-sum[j])
                max = sum[i]-sum[j];
    printf("%d",max);
}

O(n^2) 알고리즘이다.

 

sum[i]는 다음과 같이 정의된다

sum[i]: 0~i까지의 누적 합

 

따라서 sum[i] - sum[j] -> j~i 까지 연속 합이고, 그 중에서 최대를 찾는다.

 

아슬아슬하게 통과할 줄 알았지만, 시간 초과로 오답이 나왔다.

두 번째 풀이

#include <cstdio>

int main() {
    int n;
    scanf("%d",&n);
    int  in[n], dp[n], max;
    for(int i=0;i<n;++i)
        scanf("%d",&in[i]);
        
    dp[0] = in[0];
    max = in[0];
    
    for(int i=1;i<n;++i) {
        if(dp[i-1] + in[i] > in[i]) dp[i] = dp[i-1] + in[i];
        else dp[i] = in[i];
        if(dp[i] > max) max = dp[i];
    }

    printf("%d",max);
}

O(n) 시간에 수행된다.

 

dp[i]를 다음과 같이 정의하자

dp[i]: i 까지의 연속합의 최대(local maximum)

 

위와 같이 정의할 때 점화식은 다음과 같다.

dp[i-1] + a[i]: i-1까지의 연속합과 a[i] 원소를 더한 값이 a[i] 원소보다 작거나 같으면

 i.e. 연속한 음수로 a[i]를 더하면 연속 합이 더 작아지기만 하는 경우 혹은 dp[i-1] = 0으로 더해도 의미가 없는 경우, i까지 연속합의 최대를 a[i]로 설정

 

 

'Algorithms > ACMICPC(백준)' 카테고리의 다른 글

BOJ 5568 카드 놓기  (0) 2019.07.26
BOJ 2167 2차원 배열의 합  (0) 2019.07.23
BOJ 4948 베르트랑 공준  (0) 2019.07.16
BOJ 11726 2 x n 타일링  (0) 2019.07.15
BOJ 5791 거의 최단 경로  (0) 2019.07.14
Comments