연속합
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보다 작거나 같은 정수이다.
출력
첫째 줄에 답을 출력한다.
예제 입력 1
10
10 -4 3 1 5 6 -35 12 21 -1
예제 출력 1
33
예제 입력 2
10
2 1 -4 3 4 -4 6 5 -5 1
예제 출력 2
14
예제 입력 3
5
-1 -2 -3 -4 -5
예제 출력 3
-1
코드
n = int(input())
lst = list(map(int, input().split()))
arr = [0] * n
arr[0] = lst[0]
for i in range(n):
if arr[i-1] + lst[i] > lst[i]:
arr[i] = arr[i-1] + lst[i]
else:
arr[i] = lst[i]
print(max(arr))
풀이
이 문제를 보자마자 가장 먼저 떠오른 유사한 문제는 11055번이었다.
해당 문제는 특정 수열이 주어지면, 연속하지 않더라도 가장 합이 큰 부분수열의 합을 구하는 문제였다. 하지만 이 문제의 경우 특정 수열이 주어지면, 반드시 연속하는 가장 큰 합을 구하는 것이다.
전자의 경우, 이중 for문을 이용하여 바깥 for문의 인덱스가 증가함에 따라 안쪽 for문의 인덱스도 반드시 다 돌아주어야 한다. 하지만 후자의 경우, 단일 for문을 이용하여 인덱스가 증가함에 따라 단지 이전 인덱스만 비교하면 된다.
입력값 및 입력 배열을 살펴보자. 우선 연속합을 저장할 배열 arr을 0으로 초기화해두고, arr[0] = lst[0]으로 할당한다. (그 이유는 이후 for문을 위해선 0번째 인덱스 값을 반드시 미리 할당해주어야 하기 때문)
for문을 살펴보자. arr[i-1] (=> 이전 인덱스 기준 가장 큰 연속합) + lst[i] (=> 현재값)이 lst[i]보다 크면 arr[i] (=> 현재 인덱스 기준 가장 큰 연속합)을 해당 값으로 대체해준다. 예를 들어, {10 -4 6}이라는 수열에서 {10, ...}의 1번째 인덱스는 10 + (-4) > -4이기 때문에 연속합을 6(= 10 + (-4))로 대체해주는 것이다.
이 때, else문은 해당 조건이 만족하지 않는다면 arr 배열의 값은 초기값인 0으로 되어있기 때문에 반드시 현재값인 lst[i]로 대체해주어야 한다. 이는 예제 입력 3을 보면 쉽게 이해되는데 lst = {-1, -2, -3, -4, -5}은 for문을 돌면서 단 한 번도 if문을 만족하지 못하고 else문으로 넘어가게 된다. 그로 인해 arr 배열은 전부 0으로 초기화된 값으로 남기 때문에 반드시 현재값으로 대체해주어 arr = {-1, -2, -3, -4, -5}가 되어 연속합이 -1이 될 수 있다.
'Python > Coding Test' 카테고리의 다른 글
[백준] 1260 : DFS와 BFS (1) | 2023.10.30 |
---|---|
[백준] 2579 : 계단 오르기 (0) | 2023.09.18 |
[백준] 11054 : 가장 긴 바이토닉 부분 수열 (0) | 2023.09.17 |
[백준] 11055 : 가장 큰 증가하는 부분 수열 (파이썬 / Python) (0) | 2023.07.17 |
[백준] 11053 : 가장 긴 증가하는 부분 수열 (파이썬 / Python) (0) | 2023.07.17 |