본문으로 바로가기

[DP] 1912번 연속합

category Algorithm/BOJ 문제풀이 2019. 2. 6. 15:21
1912_연속합

1912번 연속합

 

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


 

문제

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

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

 

입력

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

 

출력

첫째 줄에 답을 출력한다.

 

예제 입력

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

 

예제 출력

33

 

해결방법

조건을 분석하여 문제를 해결하는 DP 문제이다

 

 

⭐️ 솔루션 ⭐️

처음에는 복잡하게 생각을 했다

연속된 경우와 비연속된 경우가 있고 포함하지 않을 수 있고...

하지만 간단히 생각해보니 이전 연속의 값에 현재 값을 더한 것현재 값 만을 비교하여 더 큰 값을 저장하면 됐다

 

 

 

소스코드

#include <iostream>
#include <cstring>
#include <math.h>
#include <algorithm>
#define MAX 100001
#define INF 987654321
using namespace std;

int n,ans;
int map[MAX];
int d[MAX];

/*
 
 순환식 : d[n-1] + map[n] > map[n] ? d[n] = d[n-1] + map[n] : d[n] = map[n]
 
 */

void dp(){
    d[1] = map[1];
    ans = d[1];
    
    for(int i=2; i<=n; i++){
        if(d[i-1] + map[i] > map[i]){
            d[i] = d[i-1] + map[i];
        }else{
            d[i] = map[i];
        }
        ans = max(ans,d[i]);
    }
    
    cout << ans << "\n";
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> n;
    for(int i=1; i<=n; i++){
        cin >> map[i];
    }
    
    dp();
    
    return 0;
}