给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。
两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括号。
例如,对于括号序列 (((),只需要添加两个括号就能让其合法,有以下几种不同的添加结果:()()()、()(())、(())()、(()()) 和 ((()))。
输入格式
输入一行包含一个字符串 s,表示给定的括号序列,序列中只有左括号和右括号。
输出格式
输出一个整数表示答案,答案可能很大,请输出答案除以 1000000007 (即 10^9+7) 的余数。
数据范围
对于 40% 的评测用例,|s|≤200。 对于所有评测用例,1≤|s|≤5000。
> 必须满足的条件
- 左右括号数量相同
- 任何一个前缀中左括号数量不少于右括号数量
import java.util.Arrays;
import java.util.Scanner;
class Main {
static int N = 5010;
static int n;
static char[] str = new char[N];
static long[][] f = new long[N][N];
static int MOD = (int) (1e9 + 7);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
for (int i = 1; i <= s.length(); i++) {
str[i] = s.charAt(i - 1);
}
n = s.length();
long l = calc();
for (int i = 1,j = n;i <= j; i++, j--) {//反转
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
for (int i = 1; i <= n; i++) {
if (str[i] == '(') str[i] = ')';
else str[i] = '(';
}
long r = calc();
System.out.println(l * r %MOD);
sc.close();
}
private static long calc() {
for (long[] tem: f) {
Arrays.fill(tem, 0);
}
f[0][0] = 1;
for (int i = 1;i <= n; i++) {
if (str[i] == '(') {
for (int j = 1; j <= n; j++)
f[i][j] = f[i - 1][j - 1];
}else {
f[i][0] = f[i - 1][0] + f[i - 1][1];
for (int j = 1; j <= n; j++) {
f[i][j] = (f[i - 1][j + 1] + f[i][j - 1]) % MOD;
}
}
}
for (int i = 0;i <= n;i++) {
if (f[n][i] != 0) return f[n][i];
}
return -1;
}
}
1613

被折叠的 条评论
为什么被折叠?



