括号匹配的方案数

题面链接

题面

牛牛最近开始学括号匹配拉

给你两个括号序列,不保证合法,求有多少种不同的方法可以将两个括号序列合并成一个合法的括号序列

合并的时候不能改变各自序列原先的顺序

输入描述:

输入两行包含两个字符串s1,s2

1 ≤  |s1|,|s2| ≤ 2500

输出描述:

输出一个整数,魔109+7
示例1

输入

(()  
())

输出

19

输入

()()()()()()()()()()()()()()()()()()()()
()()()()()()()()()()()()()()()()()

输出

487340184
示例3

输入

(((((
)))))

输出

42
示例4

输入

(())())))
(())()

输出

0

备注:

子任务一30分:max(|s1|,|s2|)<=10

子任务二30分:max(|s1|,|s2|)<=100

子任务三40分:max(|s1|,|s2|)<=2500

分析

代码

#include<bits/stdc++.h>
using namespace std;
const int N=200100;
int sum1[N],sum2[N];
int f[4000][4000];
const int mod=1e9+7;
char s1[3000],s2[3000];
int main()
{
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    int len1=strlen(s1+1);
    int len2=strlen(s2+1);
    for(int i=1;i<=len1;i++)
        sum1[i]=sum1[i-1]+(s1[i]=='('?1:-1);
    for(int i=1;i<=len2;i++)
        sum2[i]=sum2[i-1]+(s2[i]=='('?1:-1);
    f[0][0]=1;
    for(int i=0;i<=len1;i++)
        for(int j=0;j<=len2;j++)
        {
            if(sum2[j]+sum1[i]>=0)
            {
				if(i>=1) f[i][j]=(((f[i][j]+f[i-1][j])%mod)+mod)%mod;
            	if(j>=1) f[i][j]=(((f[i][j]+f[i][j-1])%mod)+mod)%mod;
            }
        }
    if(sum1[len1]+sum2[len2]!=0)cout<<0<<endl;
    else cout<<f[len1][len2]<<endl;
}

注意特判:就是当我们将两个字符串全部拼在一起的时候,如果 '('这个字符的个数还是不等于')'这个字符,就说明我们的所有方案都不合

法,直接输出0

posted @ 2020-11-05 11:46  邦的轩辕  阅读(298)  评论(0编辑  收藏  举报