| |
| |
| |
| |
| |
| |
| |
| w,h = map(int,input().split()) |
| dp = [[[[0]*2 for _ in range(2)] for _ in range(h)] for _ in range(w)] |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| for i in range(1,w): |
| dp[i][0][0][1] = 1 |
| for i in range(1,h): |
| dp[0][i][1][1] = 1 |
| |
| |
| for x in range(1,w): |
| for y in range(1,h): |
| |
| |
| |
| |
| |
| |
| dp[x][y][0][0] = dp[x-1][y][1][1] |
| dp[x][y][0][1] = dp[x-1][y][0][0] + dp[x-1][y][0][1] |
| |
| |
| |
| |
| |
| dp[x][y][1][0] = dp[x][y-1][0][1] |
| dp[x][y][1][1] = dp[x][y-1][1][0] + dp[x][y-1][1][1] |
| result = sum(dp[w-1][h-1][0]) + sum(dp[w-1][h-1][1]) |
| print(result%100000) |
다이나믹 프로그래밍를 이용해 푼 문제 중에서 내게 어려웠던 문제였다.
DP를 잘 모르는 상태에서 DP를 어떻게 설계를 해서, 저장시켜놓을지가 고민이었다.
그리고 여기서 좀 헷갈렸던 것이, DP에 이전 위치에서 올라온 방향을 저장해주는 3번째 index와, 회전이 가능한지 구분해주는 4번쨰 index가 헷갈렸다.
회전이 가능한 것은 현재 (x,y) 좌표에서 회전 가능여부를 보는 것이고, 3번째 index는 그 전 위치에서 북쪽에서 왔는지 동쪽에서 왔는지 구분해줘야했다.
서로 다른 기준점으로 인해, DP를 설계하는데 어려움을 겪었다.
위의 코드의 주석에서도 설명했지만, 총 4가지 경우를 나누어서, 정리해야한다.
1. 이전 위치에서 북쪽으로 이동해서 도착했고,, 다음번에 회전이 가능한 경우
2. 이전 위치에서 북쪽으로 이동해서 도착했고, 다음번에 회전이 불가능한 경우
3. 이전 위치에서 동쪽으로 이동해서 도착했고, 다음번에 회전이 가능한 경우
4. 이전 위치에서 동쪽으로 이동해서 도착했고,다음번에 회전이 불가능한 경우
1번 경우를 설명하자면, (x,y) 위치에 올때, 북쪽으로 이동해서 도착하고, 회전이 가능할려면, (x-1,y)에서 와야하며, 거기서도 북쪽으로 도착해야지만, 쭉 직진으로 온거기 때문에 회전이 가능하다.
이러한 경우는 [x-1][y][0][0]와 [x-1][y][0][1] 이다. 인덱스를 분석하면
[x-1][y][0][0]은 x-2,y의 위치에서 x-1,y로 북쪽으로 해서 왔고, x-2,y의 위치에서 이미 방향을 전환했기때문에, x-1,y에서 방향전환을 못하는 빨강색 화살표를 의미한다.
[x-1][y][0][1] 은 x-2,y의 위치에서 x-1,y로 북쪽으로 해서 왔고, x-2,y에서 방향전환을 안하고 왔기 때문에, x-1,y의 위치에서 방향전환이 가능한 파랑색 화살표를 의미한다.
그러므로 [x][y][0][1] = [x-1][y][0][0] + [x-1][y][0][1] 이다.
2번 경우는 (x-1,y)에서 방향전환을 해서 (x,y)를 왔기 때문에 다음번에 회전을 못하는 경우이다.
이런 경우는 (x-1,y)에서 동쪽에서 왔고, (x-1,y)에서 회전이 가능한
[x-1][y][1][1] 일때, [x][y][0][0]이 될수 있다.
3,4번 경우는 위를 회전한 것이다.
그림이 조잡해서 약간 이해하기 힘들지만, 위와 같이 총 4가지 경우를 나누어서 dp를 하면 된다.