티스토리 뷰

PS

1912. 연속합

tose33 2020. 8. 11. 19:24

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

 

1912번: 연속합

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

www.acmicpc.net

 

d[n] : a[n]을 포함하는 연속된 부분 수열들 중 그 합이 최대인 값.

 

수열이 다음과 같다고 하자.

d[0]은 자기자신 밖에없으므로 그냥 a[0]이다.

그럼 d[1]은 몇일까? 

수열이 {10, -4}이므로 원소 둘 다 더해서 10 + (-4) = 6 일수 있고, 아니면 앞의 숫자는 버리고 -4부터 시작해서 그냥 -4 일수 있다. 둘 중 큰 값은 전자 6이다.

d[2]를 보자.

수열은 {10, -4, 3}이다. 

여기서 "dp 스럽게" 생각해보자. 

d[1] 즉 {10, -4} 까지의 가장 큰 연속된 부분수열의 합이 6이다. 거기에 새로 나온 3을 더하면 9이다.

아니면 앞의 숫자를 버리고 3부터 시작할수 있다. 9와 3중 큰 수는? 9이다.

즉 d[i-1] + a[i]와 a[i]를 비교해서 큰 수가 d[i]가 된다.

이렇게 쭉 가면..

i = 7일 때를 보면.

수열은 {10, -4, 3, 1, 5, 6, -35, 12}이다. 

d[6] + a[7] = -2이다.

-2는 a[7] = 12 보다 작다. 그래서 i = 7일 때는 d[i-1] + a[i]보다 a[i]가 크다. 

그럼 앞의 숫자는 다 버리게 된다. 

 

 

d[i]를 다 채우면

d값중 가장 큰 값 33이 답이다. 수열은 {12 ,21} 인 것이다. 

 

코드

더보기
n = int(input())

a = [0] * n  # 수열 저장할 배열
d = [0] * n

a = input().split()  # 수열 입력하고 int형으로 변경 
for i in range(n):
    a[i] = int(a[i])

d[0] = a[0]
res = d[0]
# d[i-1]값과 현재 a[i]값의 합이 그냥 a[i]보다 작다면 필요가 없으니 버린다
for i in range(1, n, 1):
    d[i] = max(d[i-1] + a[i], a[i])
    res = max(res, d[i])  # 가장 큰 값 계속 갱신

print(res)

 

 

'PS' 카테고리의 다른 글

2667. 단지번호붙이기  (0) 2020.08.18
9466. 텀 프로젝트  (0) 2020.08.18
11055. 가장 큰 증가 부분 수열  (0) 2020.08.11
11054. 가장 긴 바이토닉 부분수열  (0) 2020.08.11
11722. 가장 긴 감소하는 부분수열  (0) 2020.08.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
글 보관함