====== 타일 채우기 ======
* 프로그래머스의 [[ps:problems:programmers:12902|3 x n 타일링]]과 동일한 문제이다.
* BOJ의 [[ps:problems:boj:13976|타일 채우기 2]]도 동일한 문제이다
* n의 범위만 다르다. 이 문제는 O(n)으로 풀어도 통과 가능하게 되어 있고, [[ps:problems:boj:13976|타일 채우기 2]]는 O(logn)으로 풀어야만 통과 가능하게 되어 있다.
===== 풀이 =====
* N이 홀수이면, 3xN 을 채울 수 있는 방법은 없다
* 중간에서 세로로 나누어지는 부분이 없는 3xN 타일링을 N-덩어리라고 부르자..
* {{https://onlinejudgeimages.s3-ap-northeast-1.amazonaws.com/upload/images/2663_1.jpg}}
* 이 예시는 2-덩어리, 4-덩어리, 2-덩어리, 4-덩어리로 이루어졌다
* 2-덩어리를 만드는 방법은 3가지이다
* 4-, 6-, 8-, ..., 덩어리를 만드는 방법은 2가지이다
* 그러면 3xn 벽을 채우는 방법의 수, DP[n]은
* 가장 마지막에 2-덩어리가 오는 방법의 수 => 3 * dp[n - 2]
* 가장 마지막에 4-덩어리가 오는 방법의 수 => 2 * dp[n - 4]
* 가장 마지막에 6-덩어리가 오는 방법의 수 => 2 * dp[n - 6]
* ...
* 이제 이것들을 다 더해서 dp[n]을 구할 수 있다.
*
dp[0] = 1
dp[n] = 3*dp[n-2] + 2*dp[n-4] + 2*dp[n-6] + ... + 2*dp[0] = 3*dp[n-2] + 2*sum(dp[0:n-3:2])
* 이렇게 하면 테이블 한칸을 채우는데에 O(n)이니까, 테이블을 전부 채우는데에는 O(n^2)
* 하지만, sum부분을 다시 정리하면
*
2*sum(dp[0:n-3:2]) = 2*dp[n-4] + 2*dp[n-6] + 2*dp[n-8] + ... + 2*dp[0]
= (3*dp[n-4] + 2*dp[n-6] + 2*dp[n-8] + ... + 2*dp[0]) - dp[n-4]
= dp[n-2] - dp[n-4]
* 대입하면 ''%%dp[n] = 3*dp[n-2] + (dp[n-2] - dp[n-4]) = 4*dp[n-2] - dp[n-4]%%'' 가 된다
* [[ps:선형_점화식#상수계수의 선형 점화식]]이므로, 단순히 풀면 O(n) 시간에, 행렬곱을 이용하면 O(logn) 시간에 풀이가 가능해진다
* 사실 이 문제에서는 n이 워낙 작아서, O(n^2)으로 풀든 O(n)으로 풀든, O(logn)에 풀든 시간 차이가 거의 안난다.
* 미리 30까지 테이블을 계산해서 코드에 넣어놓고 O(1)에 출력할 수도 있다.
===== 코드 =====
==== 코드 1 ====
"""Solution code for "BOJ 2133. 타일 채우기".
- Problem link: https://www.acmicpc.net/problem/2133
- Solution link: http://www.teferi.net/ps/problems/boj/2133
"""
from teflib import combinatorics
def main():
n = int(input())
print(0 if n % 2
else combinatorics.linear_homogeneous_recurrence([4, -1], [1, 3],
n // 2))
if __name__ == '__main__':
main()
* Dependency: [[:ps:teflib:combinatorics#linear_homogeneous_recurrence|teflib.combinatorics.linear_homogeneous_recurrence]]
==== 코드 2 - 행렬곱 기법을 쓰지 않고 O(n)으로 푸는 방식 ====
def main():
n = int(input())
if n % 2:
print(0)
else:
cur, prev = 3, 1
for i in range(2, n, 2):
cur, prev = cur * 4 - prev, cur
print(cur)
if __name__ == '__main__':
main()
{{tag>BOJ ps:problems:BOJ:실버_2}}