문제 : 타일링 (난이도 : 下)
분석
타일링하는 방법은 다음과 같이 2가지가 나온다.
경우의 수를 셀 때 항상 확인해야 하는 조건이 있다. 위 문제로 예를 들면 다음과 같다.
1. 이 두 가지 분류는 타일링하는 방법을 모두 포함해야 한다.
2. 두 가지 분류에 모두 포함되는 타일링 방법은 없다.
이 문제는 단계마다 세로 타일 하나로 덮을 것인지, 가로 타일 두 개로 덮을 것인지만 결정하면 된다.
남은 공간이 각각 2x(n-1), 2x(n-2)가 되므로 재귀 호출로 쉽게 답을 구할 수 있다.
2xn 크기의 사각형을 타일로 덮는 경우의 수를 반환하는 함수를 tiling(n)이라 할 때, 다음과 같은 점화식이 성립한다.
tiling(n) = tiling(n-1) + tiling(n-2)
구현
int MOD = 1000000007; //나머지로 답을 내는 이유는 overflolw를 피하기위해서 이다.
int cache[101];
// 2xwidth 사각형을 채우는 방법으 수를 MOD로 나눈 나머지를 반환한다.
int tiling(int width)
{
//base case: width가 1이하인 경우
if (width <= 1) return 1;
//memoization
int& ret = cache[width];
if (ret != -1) return ret;
return ret = (tiling(width - 1) + tiling(width - 2)) % MOD;
}
int main()
{
int c;
cin >> c;
while (c--)
{
memset(cache, -1, sizeof(cache));
int n;
cin >> n;
cout << tiling(n) << '\n';
}
return 0;
}
'알고리즘 > 알고리즘 문제 해결 전략' 카테고리의 다른 글
동적 계획법 - 10. 우물을 기어오르는 달팽이 (0) | 2021.01.03 |
---|---|
동적 계획법 - 9. 삼각형 위의 최대 경로 개수 세기 (0) | 2021.01.02 |
동적 계획법 - 7. Quantization (0) | 2020.12.31 |
동적 계획법 - 6. 원주율 외우기 (0) | 2020.12.30 |
동적 계획법 - 5. 합친 LIS (0) | 2020.12.29 |