문제
‘(‘, ‘)’ 문자로만 이루어진 문자열을 괄호 문자열이라 한다. 올바른 괄호 문자열이란 다음과 같이 정의된다. ()는 올바른 괄호 문자열이다. 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; }