#include <iostream> using namespace std; const int MAX_N = 101; const int MOD = 1000000007; int n; int cache[MAX_N]; int tiling(int n); int main() { int caseNum = 0; cin >> caseNum; for (int cIter = 0; cIter < caseNum; cIter++) { cin >> n; // Initialize for (int i = 0; i <= n; i++) cache[i] = -1; // Process int fullTiled = tiling(n); int symmetricTiled = -1; if (n == 0 || n == 1 || n == 2) symmetricTiled = n; else if (n % 2 == 0) symmetricTiled = (tiling(n / 2) + tiling((n - 2) / 2)) % MOD; else symmetricTiled = tiling((n - 1) / 2); int ret = (fullTiled - symmetricTiled + MOD) % MOD; cout << ret << endl; } } int tiling(int tileNum) { int& ret = cache[tileNum]; if (ret != -1) return ret; if (tileNum == 0) return ret = 0; else if (tileNum == 1) return ret = 1; else if (tileNum == 2) return ret = 2; ret = (tiling(tileNum - 1) + tiling(tileNum - 2)) % MOD; return ret; }
이번 문제는 전반적으로 쉽게 풀었다.
( 전체 타일링 경우의 수 ) - ( 대칭인 타일링 경우의 수 ) 를 구하면 답이 나온다.
그럼에도 시간이 오래 걸렸는데 다름아닌 Modulo 연산 때문이었다.
처음에 Modulo 에 관한 처리를 소홀하게 하였는데, 그 결과 n == 92 일 때 결과값이 자꾸 음수값이 나오는 현상이 발생하였다.
(전체 경우의 수) 에서 (부분 경우의 수) 를 마이너스 하였는데 음수값이라니...
이떄 재빨리 알아챘어야 했는데 나는 내 로직이 잘못된 줄 알고 input 값만 계속 추가해가며 테스트하였다.
이 문제에 대한 해결은 ( 전체 경우의 수 ) - ( 대칭인 타일링 경우의 수 ) 에다가 "MOD" 값을 더한 후,
다시 그 결과값에 "% MOD" 연산을 수행하는 것이었다.
Modulo는 결과값이 0 ~ (MOD - 1) 의 범위에서 순환하므로 언제든지 음수값이 나올 수 있었다.
이걸 한시간이나 걸려서 알아내다니..................................
컴퓨터와 수학 시간에 공부했던 나는 어디로 간거지..
+) MOD 값이 10^9 + 7 인 이유는
첫째 32 bit int 형 범위 내에서 표현할 수 있고,
둘째 소수 이기 때문이다.
반응형
'Algorithm > Dynamic Programming' 카테고리의 다른 글
NUMB3RS (0) | 2019.02.12 |
---|---|
POLY (0) | 2019.01.23 |
QUANTIZATION (0) | 2019.01.22 |
PI (0) | 2019.01.22 |
WILDCARD (0) | 2019.01.19 |