관리 메뉴

KorSA

ASYMTILING 본문

Algorithm/Dynamic Programming

ASYMTILING

Praiv. 2019. 1. 23. 00:54
320x100
#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 형 범위 내에서 표현할 수 있고,
   둘째 소수 이기 때문이다.


 





728x90
728x90

'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
Comments