<문제>
링크 : https://www.acmicpc.net/problem/1912
1912번: 연속합
첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
www.acmicpc.net
<코드>
import sys
input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
arr_sum = [0] * n
arr_sum[0] = arr[0]
for i in range(1, n):
if arr_sum[i-1] > 0 :
arr_sum[i] = arr_sum[i-1]+arr[i]
else:
arr_sum[i] = arr[i]
print(max(arr_sum))
<풀이>
수열의 원소를 양수들의 조합과 음수들의 조합으로 나누어 생각한다.
양수인 연속된 수열의 합이 가장 클 수 있고 음수를 일부 포함하고 연속된 수열의 합이 가장 클 수 있으므로 양수만을 고려하면 정확한 해를 찾지 못한다.
예를 들어, [양수들] [음수들] [양수들] 로 수열이 구성된 경우 가운데 있는 음수들의 합의 크기가 앞선 양수들의 합의 크기보다 작은 경우 전체 수열의 합이 연속된 수열에서 가장 큰 합을 구할 수 있고 그 크기가 음수쪽이 더 큰 경우 앞선 양수까지 연속된 수열로 포함하지 않아야 한다. -3, 4, 1 인 경우 앞의 음수는 포함하지 않고 뒤의 양수만 구성된 수열에서 가장 큰 합을 구할 수 있고 4, -3, -2, 6에서 가운데 음수를 포함하지 않는 것이 가장 큰 합을 구할 수 있게 된다.
즉, 양->음->양 으로 넘어가는 경우 음수 포함 여부를 결정하는 것이 중요한데 정리를 하자면, 경우의 수로 앞선 수열에서 합이 +, -인 경우와 특정 위치의 원소가 +, -인경우로 네가지 경우가 있고 각 경우에 따라 연속된 수열의 합이 최대가 되도록 값을 새로운 배열에 저장하도록 한다.
※ 4가지 경우의 수
- 앞선 수열의 합이 +, 특정 원소가 + : 두 값 합하기
- 앞선 수열의 합이 +, 특정 원소가 - : 두 값 합하기
- 앞선 수열의 합이 -, 특정 원소가 + : 특정 양의 원소 값으로 대체
- 앞선 수열의 합이 -, 특정 원소가 - : 특정 음의 원소 값 대체
참고 : https://github.com/Junuux/Algorithm/tree/main/Silver/1912
GitHub - Junuux/Algorithm
Contribute to Junuux/Algorithm development by creating an account on GitHub.
github.com
'Algorithm' 카테고리의 다른 글
백준 1260번 : DFS와 BFS (0) | 2022.01.16 |
---|---|
백준 1012번 : 유기농 배추 (0) | 2022.01.16 |
백준 11053번 : 가장 긴 증가하는 부분 수열 (0) | 2022.01.08 |
백준 9095번 : 1, 2, 3 더하기 (0) | 2022.01.05 |
백준 20300번 : 서강근육맨 (0) | 2022.01.05 |