문제

‘(‘, ‘)’ 문자로만 이루어진 문자열을 괄호 문자열이라 한다. 올바른 괄호 문자열이란 다음과 같이 정의된다. ()는 올바른 괄호 문자열이다. S가 올바른 괄호 문자열이라면, (S)도 올바른 괄호 문자열이다. S와 T가 올바른 괄호 문자열이라면, 두 문자열을 이어 붙인 ST도 올바른 괄호 문자열이다. (()())()은 올바른 괄호 문자열이지만 (()은 올바른 괄호 문자열이 아니다. 괄호 문자열이 주어졌을 때 올바른 괄호 문자열인지 확인하는 방법은 여러 가지가 있다.


하지만 우리가 궁금한 것은 길이가 L인 올바른 괄호 문자열의 개수이다. 길이 L이 주어졌을 때 길이가 L인 서로 다른 올바른 괄호 문자열의 개수를 출력하는 프로그램을 만들어 보자.


입력

첫 번째 줄에 테스트케이스의 개수를 나타내는 T (1 ≤ T ≤ 100)가 주어진다. 두 번째 줄부터 각 테스트케이스마다 괄호 문자열의 길이를 나타내는 L이 주어진다. (1 ≤ L ≤ 5000) 


출력

각 테스트 케이스에 대해 길이가 L인 올바른 괄호 문자열의 개수를 1,000,000,007로 나눈 나머지를 출력하시오.



long type이 8byte int라고 생각하고 알고리즘이 틀렸는지 손계산으로 앞 10개항 정도를 한참 확인했었다. long long까지 넘어가야 했다..

그리고 배열의 범위를 2500으로 줬다가, 생각해보니 0부터 정의해서 인덱스를 2500까지 사용할 수 있게 크기를 2501로 정의했어야...

여튼 해결.


#include <iostream>

const int DIVIDER = 1000000007;

long long total[2501], concat[2501], surround[2501];

int main()
{

	int n, length;
	std::cin >> n;
	
	long long result[100];

	concat[0] = 0;
	surround[0] = 0;
	total[0] = 0;
	concat[1] = 0;
	surround[1] = 1;
	total[1] = 1;
	
	for (int i = 2; i < 2501; i++) {
		surround[i] = total[i - 1];
		for (int j = 0; j < i; j++) {
			concat[i] = (concat[i] + total[j] * surround[i - j]) % DIVIDER;
		}
		total[i] = (surround[i] + concat[i]) % DIVIDER;
	}

	for (int i = 0; i < n; i++) {
		std::cin >> length;
		if (length % 2) {
			result[i] = 0;
		}
		else {
			result[i] = total[length / 2];
		}
	}

	for (int i = 0; i < n; i++) {
		std::cout << result[i] << '\n';
	}

	return 0;
}

'Exercises' 카테고리의 다른 글

백준 10942  (1) 2019.01.25
백준 5557  (0) 2019.01.22
백준 1753  (1) 2019.01.15
백준 2178  (0) 2019.01.09
백준 1260  (2) 2019.01.09

+ Recent posts