일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- Extendable hashing
- 코딩애플
- 커널 동기화
- 운영체제와 정보기술의 원리
- 프로세스 주소 공간
- 운영체제
- 개발남노씨
- B tree 데이터삽입
- concurrency control
- 네트워크
- 백엔드
- 반효경
- 트랜잭션
- 코딩테스트 [ ALL IN ONE ]
- SQL
- 인터럽트
- SDK
- 쉬운 코드
- 데이터베이스
- 쉬운코드
- Git
- 김영한
- 시스템프로그래밍
- 갤럭시 S24
- 시그널 핸들러
- recoverability
- 온디바이스AI
- vite
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- CPU 스케줄링
- Today
- Total
티끌모아 태산
1912: 연속합 본문
https://www.acmicpc.net/problem/1912
1912번: 연속합
첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
www.acmicpc.net
설명
n개의 정수로 이루어진 수열에서 연속된 몇 개의 수를 선택해 가장 큰 합을 출력하는 프로그램 작성. 예를들어, 10, -4, 3, 1, 5, 6, -35, 12, 21, -1 이라는 수열이 주어졌을 때, 정답은 12 + 21 인 33이다.
핵심 아이디어
- 최대 계산 값을 계속 기록하면서, 최대한 빠른 시간 안에 해결하는 것이다.
- Memorization(기억법)을 활용하는 것으로 대표적이로 DP 스킬 중 하나이다.
- i번째 데이터 이전까지의 합을 계산하고 최댓값을 지속적으로 기록한다. 이때, 이전까지의 합이 i번째 숫자보다 작은 경우 이전의 기록들은 무의미하다. 따라서 i번째 숫자를 최댓값으로 설정한다. max() 활용
실제 작은 문제부터 계산해보면
첫 번째: Loop i = 1 인 경우, data[1] = max(-4, -4+10=6) -> data[1] = 6. 따라서 6은 이전까지 연속된 합 중 최댓값을 기록한 것이다. DP-Memorization
data = [ 10, 6 , 3, 1, 5, 6, -35, 12, 21, -1 ]
두 번째: Loop i = 2 인 경우, data[2] = max(3, 3+6=9) -> data[2] = 9. 따라서 9는 이전까지 연속된 합 중 최댓값을 기록 한 것이다.
data = [ 10, 6, 9 , 1, 5, 6, -35, 12, 21, -1 ]
...
이런 식으로 반복문을 돌다가 다 돌았을 때 나오는 결과는 다음과 같다.
data = [10, 6, 9, 10, 15, 21, -14, 12, 33, 32] 이고 max(data) = 33 이 정답으로 출력되는 것이다. 이런식으로 작은 문제부터 풀어보자!
코드 구현
n = int(input())
data = list(map(int, input().split()))
# 반복문을 1에서 시작하는 이유
# 이전까지 모든 숫자의 합 중 최댓값을 그때 그때 기록하는 것
# 데이터의 시작점이 0번 인덱스는 이전까지의 합이 0 자신 자체이기 때문에
# 아무런 필요가 없다.
for i in range(1, n):
# i번째 데이터를 업데이트 하는 이유
# i번째 인덱스는 핵심코드의 논리인 "이전까지 모든 숫자의 합 중 최댓값"
# 이기 때문에 업데이트 해야한다.
data[i] = max(data[i], data[i-1]+data[i])
print(max(data))
# print(data): [10, 6, 9, 10, 15, 21, -14, 12, 33, 32]
반복문을 1부터 시작하는 이유는 "이전까지 모든 숫자의 합 중 최댓값"을 계속해서 기록하는 것인데, 데이터 0부터 시작하게 되면 이전까지의 합이 0이다. 따라서 0 즉, 자기 자체이기 때문에 필요가 없다. 그렇기 때문에 index 1부터 시작하는 것이다.
그리고 i번째 index는 "이전까지 모든 숫자의 합 중 최댓값"이기 때문에 업데이트를 계속 해주어야 한다.
'백준 문제 > DP' 카테고리의 다른 글
2156: 포도주 시식 (0) | 2024.03.10 |
---|---|
2193: 이친수 (0) | 2024.03.10 |
11659: 구간 합 구하기 4 (0) | 2024.03.09 |