티스토리 뷰
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
- dfs
- graph
- Tree
- binary search
- C
- recursion
- Kruskal
- 재귀
- Implementation
- two pointer
- back tracking
- Dijkstra
- DP
- Python
- BFS
- 이분탐색
- Brute Force
- 자료구조
- C++
- db
- floyd warshall
- Spring
- priority queue
- CSS
- MVC
- Stack
- Unity
- 조합
- permutation
- greedy
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
