DP를 정~~말 어려워하는 제가 어떻게 이해했는지 적어보겠습니다!😆
가로 파이프는 이전에 설치한 파이프가 가로, 대각선일때 설치할 수 있죠.
세로 파이프는 이전에 설치한 파이프가 세로, 대각선일때 설치할 수 있어요.
대각선 파이프는 이전에 설치한 파이프가 대각선, 가로, 세로 모든 경우에서 설치 가능해요.
벽을 고려해주어야 하는데요벽이 없어야 하는건 당연한거니까, 대각선 파이프를 설치할때만 특별히 주의하시면 돼요~대각선 파이프를 설치하기 위해서는 아래 사진처럼 파이프를 새로 추가하려는 칸 뿐아니라 왼쪽, 위쪽 또한 벽이 없어야 돼요! (즉, 아래 사진의 색칠된 칸 모양┘에 벽이 없어야 돼요) 여기까지는 어렵지 않게 이해하셨죠😉?
dp라는 3차원 그래프에 담아보려고 해요! 우선 그림을 통해서 어떤식으로 담을지 보여드릴게요.우선 벽 유무에 관한 (문제에서는 '집의 상태'라고 하더라고요?) 집 그래프를 board라고 할게요. board는 그냥 input을 그대로 가져옵시다. (예시는 그냥 아무 예시나 가져와봤어요!)

이걸 바탕으로 dp의 초기 상태를 가져와보면 다음과 같아요.


dp로 표현해보면 아래와 같겠네요!
가로 또는 세로 또는 대각선 파이프가 1개 존재한다는 말이겠네요! 흠...이해되시나요😮?dp로 풀어봅시다!
dp에 표시해줍시다.
가로이기 때문에 1열에는 파이프의 끝이 오는 경우가 없다는 것을 금방 알아차릴 수 있을 거예요.
board[1][1] 부터 처리해갈 거예요! 1행과 1열은 이미 3번, 4번 과정에서 다 처리를 해줬으니까~😉board에서 벽이 있는지 없는지 검사해보고 (가로, 세로, 대각선) 파이프를 설치할 공간이 있는지 판단해요!dp에 결과를 저장해줍니다!아직 이게 무슨말인지 살~짝 알듯말듯 하니까 다시 그림으로 차근차근 이해해봐요 :)

- 이게 살짝 헷갈릴수도 있는데.. 가장 중요한 것은!!
dp에 저장되는 값은 파이프의 끝의 개수를 가리킨다는 점이에요!- 아래 사진에서
dp를 왜 저렇게 표현했는지 완벽하게 이해하고 넘어가세요..!
[1] 먼저 벽의 유무를 고려해봐요.
0으로 벽이 없죠? → 가로, 세로 파이프를 설치할 공간이 있어요.0이네요. → 대각선 파이프를 설치할 공간이 있어요. 가로, 세로, 대각선 파이프 모두 설치할 공간이 충분히 있네요!dp를 갱신해주면 돼요.[2], [3] 각 파이프의 종류에 따라서 dp를 갱신해줘요
가로 파이프는 이전 파이프가 가로, 대각선인 경우만 설치할 수 있다고 했죠?dp 값을 갱신해줍시다!가로 파이프 끝 개수]와 [왼쪽 칸의 대각선 파이프 끝 개수]를 더하면, [현재 가로 파이프의 끝 개수]가 되겠죠? (근데 실제로는 다 0(아래 그림에서 노란색 칸 dp)이여서 갱신한 값도 그대로 0이네요~~)
세로 파이프는,현재 칸의 세로 파이프의 끝 개수 = 위쪽 칸의 세로 파이프 끝 개수 + 위쪽 칸의 대각선 파이프 끝 개수 가 될 것이고...
대각선 파이프를 놓는 경우에 대해서는현재 칸의 대각선 파이프의 끝 개수 = (왼쪽 위 대각선)칸의 가로 파이프 끝 개수 + (왼쪽 위 대각선)칸의 세로 파이프 끝 개수 + (왼쪽 위 대각선)칸의 대각선 파이프 끝 개수)
이런 방법으로 계속해서 dp를 메모이제이션 방법으로 채워가시면 됩니다!
코드는 아래와 같아요. 코드를 이해할때 주의할 점은 dp는 가로, 세로, 대각선 칸을 구현하기 위해 3차원 배열을 사용했어요. 설명은 아래에 써놨어요!
dp[0][row][col] = 가로 파이프에 대한 dpdp[1][row][col] = 대각선 파이프에 대한 dpdp[2][row][col] = 세로 파이프에 대한 dp# 0 → ─, 1 → /, 2 → |
def solution():
# 1행 미리 처리하기 → (3) 과정
dp[0][0][1] = 1
for i in range(2, N):
if board[0][i] == 0:
dp[0][0][i] = dp[0][0][i - 1]
# 왜 1행과 1열을 제외하는지는 (3), (4) 과정에서 봤었죠?
for r in range(1, N):
for c in range(1, N):
# (5) 과정
# 대각선 파이프를 추가하는 과정
if board[r][c] == 0 and board[r][c - 1] == 0 and board[r - 1][c] == 0:
dp[1][r][c] = dp[0][r - 1][c - 1] + dp[1][r - 1][c - 1] + dp[2][r - 1][c - 1]
# 가로, 세로 파이프를 추가하는 과정
if board[r][c] == 0:
dp[0][r][c] = dp[0][r][c - 1] + dp[1][r][c - 1]
dp[2][r][c] = dp[2][r - 1][c] + dp[1][r - 1][c]
# 최종 결과 출력
print(sum(dp[i][N - 1][N - 1] for i in range(3)))
N = int(input())
board = [list(map(int, input().split())) for _ in range(N)]
dp = [[[0 for _ in range(N)] for _ in range(N)] for _ in range(3)]
solution()
감사합니다ㅠㅠ 드디어 이해가 되네요