2096번: 내려가기
첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.
www.acmicpc.net
비슷한 문제로는 RGB 거리 문제가 떠오른다. 전형적인 DP문제로 쉽게 풀 것이라고 생각했지만 모든 dp문제가 다 그렇듯이 문제마다 요구하는 특별한 방법이 있기 때문에 상황 파악이 우선이다. 필자는 이 문제를 풀 때 잘못된 접근을 하여 한동안 헤맸었다. 잘못된 접근 법은 아래에 정답 코드 이후에 설명하겠다.
접근
문제의 조건을 보면 N이 100000까지 커질 수 있기 때문에 2차원 dp N*3짜리를 만드는 것은 별로 효율적이지 않다. 따라서 dp리스트는 3*1짜리로만 풀 것이고 새로운 입력을 받을 때마다 dp를 업데이트시켜줄 것이다. 예를 들어 예제 1과 같은 입력을 받았다고 생각해 보자(최대 값을 구하는 방법으로 한정해서 생각해 보자).
3
1 2 3
4 5 6
4 9 0
먼저 dp에 [1 2 3]을 넣어준다.
그다음에 [4 5 6] 을 입력받은 후 이 리스트를 ls라고 칭하겠다. 이제 아래와 같은 방식으로 화살표를 따라 최댓값 연산을 해주면 된다.
이 과정을 N-1회 해주면 된다.
시도 1(Python)
import sys
input = sys.stdin.readline
n = int(input())
ls = list(map(int, input().split()))
dp_max = ls[:]
dp_min = ls[:]
for i in range(1, n):
ls = list(map(int, input().split()))
ls2 = ls[:]
ls[0], ls[1], ls[2] = ls[0] + max(dp_max[0], dp_max[1]), ls[1] + max(dp_max), ls[2] + max(dp_max[2], dp_max[1])
dp_max = ls[:]
ls = ls2[:]
ls[0], ls[1], ls[2] = ls[0] + min(dp_min[0], dp_min[1]), ls[1] + min(dp_min), ls[2] + min(dp_min[2], dp_min[1])
dp_min = ls[:]
print(max(dp_max), min(dp_min))
잘못된 접근 방법
위에서는 아래의 ls값에서 그 이전 입력(dp)에 접근했었다면 이번에는 반대로 dp값을 기준으로 ls로 내려가보자. 이렇게 되면 문제가 하나 생긴다.
오른쪽 그림과 같이 왼쪽 끝은 절대 오른쪽 끝을 건드리지 못하기 때문에 잘못된 결과물로 이어질 수도 있다.
'백준 > Gold(1~5)' 카테고리의 다른 글
[백준]_2239번, 2580번 : 스도쿠(파이썬) (2) | 2023.11.18 |
---|---|
[백준]_2565번 : 전깃줄(파이썬 and C언어) (0) | 2023.11.07 |
[백준]_11758번 : CCW(파이썬 and C언어) (0) | 2023.09.17 |
[백준]_7576번 : 토마토(파이썬) (0) | 2023.08.23 |
[백준]_1461번 : 도서관(파이썬 and C언어) (0) | 2023.08.09 |