‘(‘, ‘)’ 문자로만 이루어진 문자열을 괄호 문자열이라 한다. 올바른 괄호 문자열이란 다음과 같이 정의된다. ()는 올바른 괄호 문자열이다. S가 올바른 괄호 문자열이라면, (S)도 올바른 괄호 문자열이다. S와 T가 올바른 괄호 문자열이라면, 두 문자열을 이어 붙인 ST도 올바른 괄호 문자열이다. (()())()은 올바른 괄호 문자열이지만 (()은 올바른 괄호 문자열이 아니다. 괄호 문자열이 주어졌을 때 올바른 괄호 문자열인지 확인하는 방법은 여러 가지가 있다.
하지만 우리가 궁금한 것은 길이가 L인 올바른 괄호 문자열의 개수이다. 길이 L이 주어졌을 때 길이가 L인 서로 다른 올바른 괄호 문자열의 개수를 출력하는 프로그램을 만들어 보자.
첫 번째 줄에 테스트케이스의 개수를 나타내는 T (1 ≤ T ≤ 100)가 주어진다. 두 번째 줄부터 각 테스트케이스마다 괄호 문자열의 길이를 나타내는 L이 주어진다. (1 ≤ L ≤ 5000)
각 테스트 케이스에 대해 길이가 L인 올바른 괄호 문자열의 개수를 1,000,000,007로 나눈 나머지를 출력하시오.
3
1
2
4
0
1
2
이 문제는 다이나믹 프로그래밍 알고리즘을 이용하면 풀 수 있었다. 이 문제를 풀기 위해선 카탈란 수를 알아야 한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
static long[] dp;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
dp = new long[5001];
dp[0] = 1;
dp[1] = 1;
for(int i=2; i<=5000; i++)
dp[i] = sol(0, i-1)%(1000000007);
for(int i=0; i<T; i++) {
int n = Integer.parseInt(br.readLine());
if(n%2!=0)
System.out.println(0);
else
System.out.println(dp[n/2]%(1000000007));
}
}
public static long sol(int n, int m) {
if(m==0)
return (dp[n]*dp[0])%(1000000007);
return (dp[n]*dp[m])+sol(n+1, m-1)%(1000000007);
}
}