2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오.
아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.
첫째 줄에 n이 주어진다. (1 ≤ n ≤ 1,000)
첫째 줄에 2×n 크기의 직사각형을 채우는 방법의 수를 10,007로 나눈 나머지를 출력한다.
2
2
n 일때 2xn 크기의 직사각형을 1x2, 2x1 타일로 채우는 방법의 수를 f(n) 이라 할때 다음과 같은 점화식이 성립한다.
f(n) = f(n-1) + f(n-2) (n > 2, n은 자연수)
n = int(input())
dp = [0] * 1001
dp[1],dp[2],dp[3] = 1,2,3
for i in range(4, n+1):
dp[i] = (dp[i-1] + dp[i-2]) % 10007
print(dp[n])
1
n 을 입력 받고, 크기가 n+1 인 배열을 생성한 후, dp[0], dp[1], dp[2] 의 값을 초기화는 것을 생각했다.
그러다 보니 n 이 1인 경우에 배열의 크기가 2가 되어 dp[2] 의 값을 입력하려고 할때 indexError 가 발생했다.
이를 해결하기 위해 n < 3 인 경우에 대해 선제적으로 값을 출력한뒤 종료 시키고, 그렇지 않은 경우에 대해 크기가 n+1 인 배열을 만들고 dp[0],dp[1],dp[2]에 값을 할당하였다.
n = int(input())
if n < 3:
print(n)
exit()
dp = [0 for _ in range(n+1)]
dp[0], dp[1], dp[2] = 0, 1, 2
for i in range(3, n+1):
dp[i] = (dp[i-1] + dp[i-2]) % 10007
print(dp[n])
그러나 이렇게 n 의 크기에 따라 indexError 가 발생할 잠재적인 위험을 제거하기 위해 문제에서 이미 제공하고 있는 n 의 범위(1~1000)을 참고하여 1001 크기의 배열을 미리 생성하는 방법을 사용할 수 있다.
그리고 새롭게 알게 된 사실, range(start, end) 에서 start >= end 여도 에러가 발생하지 않는다. 실행이 되지 않을 뿐이다. range(start, end, -1) 과 같이 역순으로 내려가는 경우도 있기 때문에 이렇게 처리가 되지 않았을까 싶다.
더 나은 풀이
n = int(input())
dp = [0 for _ in range(0, 1001)] # 0 ~ 1000 의 인덱스 가짐
dp[0], dp[1], dp[2] = 0, 1, 2
for i in range(3, n+1):
dp[i] = (dp[i-1] + dp[i-2]) % 10007
print(dp[n])