2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하는 문제입니다.
자주 접할 수 있는 DP문제(다이나믹 프로그래밍) 유형입니다.
보통 DP문제는 피보나치 수열, 재귀함수 등을 이용하여 해결 가능합니다.
#include <iostream>
using namespace std;
int dp[1001];
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int num;
cin >> num;
dp[1]=1;
dp[2]=2;
for(int i=3; i<=num; i++){
dp[i] = dp[i-1]+dp[i-2];
dp[i]%=10007;
}
cout << dp[num];
return 0;
}
DP문제임을 파악하면 규칙을 찾아내어 함수를 쉽게 유추할 수 있습니다.
먼저 타일이 n개일 때, 2 x 1모양의 타일을 붙이는 가지수를 f(n)이라 가정합니다.
그러면 n=1일 때 , 2 x 1에서는 하나의 타일만 들어가므로
" l "
f(1) = 1
n=2 일 때, 2 x 2 아래처럼 두가지 경우로
" l l ", " = "
f(2) = 2
n=3 일 때,
" lll " , " l= ", " =l "
f(3) = 3
n=4 일 때,
" llll ", " l=l ", " =ll ", " ll= ", == "
f(4) = 5
여기서 n=4 인 경우를 생각해보면,
" llll ", " l=l ", " =ll " 이 경우 n=3인 경우에서 제일 오른쪽에 2 x 1 타일을 하나 붙인 것과 모양이 같습니다.
즉, 2 x 1 타일 하나가 맨 왼쪽에 고정되어 있다고 볼 수 있습니다.
이를 다시 생각하면 맨 오른쪽에는 2 x 2 타일을 고정시키는 경우의 수로 볼 수 있습니다.
여기서 순열에 원리를 이용하여 한자리가 고정된 경우의 수를 (n-1)! 으로 보고 이를 적용시키면 됩니다.
따라서 2 x 1, 2 x 2의 경우의 수를 이용하여 dp 배열의 값을 선언합니다.
dp[1]=1, dp[2]=2
이후 dp[i] = dp[i-1] + dp[i-2] 로 나머지 배열을 완성하면 됩니다.
( 재귀함수를 이용할 수 있지만 시간초과)
.
.
.
한국항공대학교 2022-2 알고리즘 설계 해석 기말고사 5번문제
'알고리즘 > 백준' 카테고리의 다른 글
C++ 백준 BOJ 1620 나는야 포켓몬 마스터 이다솜 (0) | 2022.12.27 |
---|---|
C++ 백준 BOJ 1212 8진수 2진수 (0) | 2022.11.15 |
C++ 백준 BOJ 10870 피보나치 수 5 (0) | 2022.07.27 |
C++ 백준 BOJ 9012 괄호 (0) | 2022.07.25 |
C++ 백준 BOJ 2960 에라토스테네스의 체 (0) | 2022.04.30 |
댓글