평범한 dp문제이지만, 왜인지 안 풀리다가 나중에 내 오류를 발견한 문제. 처음 생각한 논리 구조는 다음과 같다.
[[0, 0] for _ in range(n+1)]
. 이는 [앞 잔을 안 먹고 현재 잔 먹음, 앞 잔을 먹고 현재 잔 먹음]
을 의미한다.for
반복문을 돌며 앞 잔을 먹고 현재 잔을 먹는 경우와 앞 잔을 먹지 않고 현재 잔을 먹는 경우 마실 수 있는 포도주 양을 저장한다. dp[i-1][0]
의 값과 현재 잔의 값을 더한다.max(dp[i-2])
에 현재 잔의 값을 더해서 구한다.dp[i][0] = max(dp[i - 2]) + arr[i - 1]
dp[i][1] = dp[i - 1][0] + arr[i - 1]
하지만 위와 같이 하면 다음과 같은 반례가 생긴다.
<입력>
6
1
1
0
0
1
1
<출력 되어야 하는 것>
4
<출력되는 것>
3
이유는 위의 논리구조는 현재 잔을 마실 때 이전 잔 혹은 그 이전 잔 중 하나는 반드시 마신다고 가정하고 있기 때문이다. 따라서 OOXXOO
와 같은 경우를 고려하지 못한다.
이 문제는 현재 잔을 먹지 않는 경우
도 포함하면 해결할 수 있다. 고친 논리구조는 다음과 같다.
[[0, 0, 0] for _ in range(n+1)]
. 이는 [이번 잔 안 먹음, 앞 잔을 안 먹고 현재 잔 먹음, 앞 잔을 먹고 현재 잔 먹음]
을 의미한다.for
반복문을 돌며 현재 잔을 안 먹는 경우, 앞 잔을 먹고 현재 잔을 먹는 경우, 앞 잔을 먹지 않고 현재 잔을 먹는 경우 마실 수 있는 포도주 양을 저장한다. max(dp[i-1])
를 저장한다.dp[i-1][0]
의 값과 arr[i]
의 값을 더한다. (정확히는 arr[i-1]
이다)dp[i-1][1]
의 값과 현재 잔의 값을 더한다.좀 복잡해보이지만, 코드로 정리하면 의외로 단순하다.
import sys
input = sys.stdin.readline
n = int(input())
arr = [int(input()) for _ in range(n)]
dp = [[0, 0, 0] for _ in range(n + 1)] # [현재 잔 안 먹음, 앞 잔을 안 먹고 현재 잔 먹음, 앞 잔을 먹고 현재 잔 먹음]
dp[1] = [0, arr[0], arr[0]]
for i in range(2, n + 1):
dp[i][0] = max(dp[i - 1])
dp[i][1] = dp[i - 1][0] + arr[i - 1]
dp[i][2] = dp[i - 1][1] + arr[i - 1]
print(max(dp[-1]))