https://www.acmicpc.net/problem/11726
11726번: 2×n 타일링
2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오. 아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.
www.acmicpc.net
문제
2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오.
아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.

입력
첫째 줄에 n이 주어진다. (1 ≤ n ≤ 1,000)
출력
첫째 줄에 2×n 크기의 직사각형을 채우는 방법의 수를 10,007로 나눈 나머지를 출력한다.

💻 코드
방법 1)
BottomUp 방식 : 반복문 사용
import sys
d = [0] * 10001
def RectangleCount(x):
d[1] = 1
d[2] = 2
for i in range(3, x + 1):
d[i] = d[i - 1] + d[i - 2]
return d[x]
n = int(sys.stdin.readline())
print(RectangleCount(n) % 10007)
방법 2)
TopDown 방식 : 재귀 함수 사용
import sys
d = [0] * 10001
def RectangleCount(x):
d[1] = 1
d[2] = 2
for i in range(3, x + 1):
d[i] = d[i - 1] + d[i - 2]
return d[x]
n = int(sys.stdin.readline())
print(RectangleCount(n) % 10007)
📝 풀이
이 문제는 풀이 과정을 생각해내는 데에 오래 걸렸던 문제이다. n이 1일 경우부터 6일 경우까지의 경우의 수를 그려서 규칙을 찾아내었다. 이 규칙을 찾아내는 과정이 막혔던 부분이었는데 여러 가지 방법을 시도함으로써 해결할 수 있었다.
n이 1일 경우부터 n이 6일 경우의 수를 그림으로 그린 것이다.

이렇게 그림으로 그린 다음 체계적으로 박스가 어떻게 만들어지는지 살펴보니까 쉽게 풀렸었다. (처음에 너무 복잡하게 생각했던 것 같다. 이 문제를 풀면서 깨달은 것은 규칙을 찾을 때 체계적으로 봐야 한다는 것이다.)
1. 규칙 찾기
그림에서 볼 수 있듯이 n이 3일 때, n - 1 부분에 선을 그으면 n이 2일 때 경우의 수가 들어있고 n - 2 부분에 선을 그으면 n이 1일 때 경우의 수가 들어있다. n이 4일 때, n - 1 부분에 선을 그으면 n이 3일 때 경우의 수가 들어있고 n - 2 부분에 선을 그으면 n이 2일 때 경우의 수가 들어있다. 이와 같이 n이 커졌을 경우에도 이것이 반복됨을 알 수 있다.
2. 어떤 방법으로 풀어야할지(알고리즘) 생각해보기
처음에는 부분 문제들이 재귀적으로 반복된다고 생각하여 다이나믹 프로그래밍 문제라고 생각했고 재귀 함수를 만들어서 풀었다.
작성한 코드는 다음과 같다.
import sys
d = [0] * 1000
def RectangleCount(x):
if x == 1:
return 1
if x == 2:
return 2
if d[x] != 0:
return d[x]
d[x] = RectangleCount(x - 1) + RectangleCount(x - 2)
return d[x]
n = int(sys.stdin.readline())
print(RectangleCount(n) % 10007)
그런데 채점을 해보니 런타임 에러가 발생하였다. 그래서 다시 테스트를 해보았더니 999까지는 정상적으로 작동하였는데 1000을 입력하니까 에러가 났었다.
RecursionError: maximum recursion depth exceeded in comparison
이 에러는 재귀와 관련된 에러이다. 이 에러는 python이 정한 최대 깊이보다 재귀의 깊이가 더 깊기 때문에 발생한다. 이를 해결하는 방법은 두 가지 방법이 있다.
첫 번째) 재귀 함수를 쓰지 않는 방법 (반복문 사용)
이 문제는 다이나믹 프로그래밍의 BottomUp 방식으로 반복문을 사용해서도 풀 수 있다.
반복문을 사용한 풀이는 코드 방법 1)에서 확인할 수 있다.
두 번째) python이 정한 최대 재귀 깊이를 변경하는 방법
sys.setrecursionlimit() 함수를 사용하면 최대 재귀 깊이를 변경할 수 있다.
sys.setrecursionlimit(10**4)
와 같이 입력하면 최대 재귀 깊이를 10,000 정도로 크게 설정할 수 있어 런타임 에러 없이 실행된다.
재귀 함수를 사용한 풀이는 코드 방법 2)에서 확인할 수 있다.
※ 참고
https://help.acmicpc.net/judge/rte/RecursionError
런타임 에러 (RecursionError)
RecursionErrorRecursionError는 재귀와 관련된 에러입니다. 가장 많이 발생하는 이유는 Python이 정한 최대 재귀 깊이보다 재귀의 깊이가 더 깊어질 때입니다.Python이 정한 최대 재귀 깊이는 sys.getrecursionli
help.acmicpc.net
'Algorithm 문제 풀이 > python' 카테고리의 다른 글
[python] 백준 11727번 2 X n 타일링 2 (0) | 2022.07.15 |
---|---|
[python] 백준 1406번 에디터 문제 풀이 (0) | 2022.07.13 |
[python] 백준 1463번 1로 만들기 문제 풀이 (0) | 2022.06.25 |
[python] 백준 6588번 골드바흐의 추측 문제 풀이 (0) | 2022.06.22 |
[python] 백준 1929번 소수 구하기 (0) | 2022.06.21 |