[프로그래머스] (Lv.2) 3 x n 타일링
LastMod:
👨💻 개인 공부 기록용 블로그 입니다.
💡 틀린 내용이나 오타는 댓글, 메일로 제보해주시면 감사하겠습니다!! (__)
링크Permalink
https://school.programmers.co.kr/learn/courses/30/lessons/12902
문제Permalink
문제 설명 및 요점Permalink
- 단위 타일의 크기는 2x1 이다.
- 가로의 길이
은 5000 이하의 자연수이다. 또한 세로 길이가 3 이므로, 은 2의 배수여야만 한다. 이 2의 배수가 아니라면, 길이가 짝수인 단위 타일로는 넓이가 홀수인 타일을 채울 수 없다.
- 경우의 수를 1000000007로 나누어 리턴해야 한다.
풀이Permalink
#DP
- 타일링 문제는 DP로 분류된다.
- 이전 타일 배치 경우의 수가 지속적으로 활용되기 때문이다.
- 점화식을 찾아보자.
인 경우는 간단하게 구할 수 있으며, 인 경우의 수는 문제에 주어져 있다.
dp[n] = 가로가 n일때, 3xn 타일링의 경우의 수
라고 정의해보자.
dp[4] = dp[2] * dp[2] + ?
로 볼 수 있다. 가로 길이 4를 2와 2로 쪼갤 수 있고, 가로 길이 2는 dp[2]
를 통해 이미 구했기 때문이다. 하지만 + ?
로 적어놨듯, 아직 구해지지 않은 무언가가 있다.
입출력 예시에도 나와있는데, 아래와 같이
따라서 + ?
자리에는 2
가 들어간다.
dp[4]
를 통해 가로 길이가 4일 때를 계산하였고, 거기에 가로 길이 2가 늘어난 경우로 볼 수 있다. 이 경우는 dp[4] * dp[2]
로 계산할 수 있다.
또한, dp[4]
를 계산할 때 dp[2] * 2(유니크한 단위 타일)
로 계산할 수 있다. 유니크한 단위 타일의 가로 길이가 4였기 때문에 dp[2]
를 곱해주었다.
이전 경우와 마찬가지로,
유니크한 단위 타일을 잘 보면, 이것이 만들어지는 규칙을 도출해낼 수 있다. 윗변 또는 밑변이 가로 타일로만 이루어져 있으며, 양 끝은 세로 타일이 들어간다는 점이다. 이로 미루어 보아,
위 케이스들을 통해, 점화식을 도출해보자.
dp[0] = 1
로 초깃값을 두어 유니크한 단위 타일에 대한 경우의 수 계산을 간단히 할 수 있다. dp[2] = 3
이므로, 아래와 같이 코드를 작성하면 통과할 수 있다.
def solution(n):
INF = 1_000_000_007
dp = [0] * 5001
dp[0] = 1
dp[2] = 3
for i in range(4, n + 1, 2):
dp[i] = (dp[i - 2] * 3)
for j in range(i - 4, -1, -2):
dp[i] += (dp[j] * 2)
return dp[n] % INF
프로그래머스 시간 제한이 넉넉해서 위 코드로도 충분히 통과할 수 있지만, 위 코드는
점화식의
위 수식으로 부터, 양변에서
이므로, 위 수식으로 점화식의 우항을 정리할 수 있으며, 최종 점화식은 다음과 같다.
코드Permalink
def solution(n):
INF = 1_000_000_007
dp = [0] * 5001
dp[0] = 1
dp[2] = 3
for i in range(4, n + 1, 2):
dp[i] = (dp[i - 2] * 4 - dp[i - 4]) % INF
return dp[n]
Leave a comment