본문 바로가기

Algorithm

백준 10422번 괄호

반응형

문제

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

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

입력

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

출력

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

 

DP는 진짜 어렵다.. 골드 정도만 되도 체감상 완탐이나 string 플레 정도 느낌..?

아이디어는 D[n]이 길이 n의 올바른 괄호 개수라면

( -------------------- )[               ]

처음의 여는 괄호에 대응되는 닫는 괄호가 i 번째에 위치한다면 그 안에 있는 ---------------------영역은 D[i-2]

그리고 [     ] 영역은 전체 n에서 i만큼 빠지므로 D[n - i]가 된다.

따라서 D[n] = D[i-2] * D[n - i]이고 

정답을 인정받으려면 n이 증가할수록 카운트가 급증하기 때문에 long long 자료형에

% 1,000,000,007을 한번에 해주면 이미 해주기 전에 값이 long long 범위를 초과하여 쓰레기 값이 되므로

매번 더해질때마다 해줘야 함.

#include<iostream>
#include <string.h>
#include<string>
#include<queue>
#include <vector>
#include<map>

using namespace std;

long long D[5001];
void init()
{
	D[0] = 1;
	D[2] = 1;

	for (int i = 3; i <= 5000; i++)
	{
		for (int j = 2; j <= i; j++)
		{
			D[i] += D[j - 2] * D[i - j];
		}
		D[i] %= 1000000007;
	}
}

int main(void)
{
	int tc;
	cin >> tc;
	
	init();

	for (int t = 0; t < tc; t++)
	{
		int n;
		cin >> n;
		cout << D[n] << endl;
	}
}
반응형

'Algorithm' 카테고리의 다른 글

백준 11780번 플로이드 2  (0) 2020.08.30
백준 15992번 1, 2, 3 더하기 7  (0) 2020.08.29
백준 1644번 - 소수의 연속합  (0) 2020.08.17
백준 16954번 움직이는 미로 탈출  (0) 2020.08.16
백준 12886번 돌 그룹  (0) 2020.08.16