标签:Sequence 蔚来 rep 多校 括号 Longrightarrow longrightarrow dp MOD
K Link with Bracket Sequence I
题目大意:给定一个长度为\(n\)的括号序列\(a\),\(a\)是一个长度为\(m\)的合法括号序列\(b\)的子序列,求\(b\)的方案数
(\(mod\ 10^9+7,1<=n<=m<=200\) )
解题思路:考虑类似最长公共子序列的动态规划,加上括号序列需要合法的限制
\[dp[i][j][k]:=b的前i个最多匹配a的前j个,剩下k个左括号未匹配的方案数 \]定义状态:
\[a_{j+1}==')'\ \ \Longrightarrow \ \ dp[i][j][k]\longrightarrow dp[i+1][j][k+1]\\ a_{j+1}=='('\ \ \Longrightarrow \ \ dp[i][j][k]\longrightarrow dp[i+1][j+1][k+1] \]状态转移:
\(b\)多放一个左括号
\[a_{j+1}=='('\ \ \Longrightarrow \ \ dp[i][j][k]\longrightarrow dp[i+1][j][k-1]\\ a_{j+1}==')'\ \ \Longrightarrow \ \ dp[i][j][k]\longrightarrow dp[i+1][j+1][k-1] \]\(b\)多放一个右括号
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (int)(a); i <= (int)(b); i ++)
const int N = 210, MOD = 1e9 + 7;
int dp[N][N][N];
char a[N];
void work() {
int n,m;
cin>>n>>m>>a+1;
memset(dp,0,sizeof dp);
dp[0][0][0]=1;
rep(i,0,m-1){
rep(j,0,min(i,n)){
rep(k,0,i){
// '('
if(a[j+1]=='(') dp[i+1][j+1][k+1]=(dp[i+1][j+1][k+1]+dp[i][j][k])%MOD;
else dp[i+1][j][k+1]=(dp[i+1][j][k+1]+dp[i][j][k])%MOD;
// ')'
if(!k) continue;
if(a[j+1]==')') dp[i+1][j+1][k-1]=(dp[i+1][j+1][k-1]+dp[i][j][k])%MOD;
else dp[i+1][j][k-1]=(dp[i+1][j][k-1]+dp[i][j][k])%MOD;
}
}
}
cout<<dp[m][n][0]<<endl;
}
signed main() {
int test=1;
cin >> test;
while (test--)
work();
return 0;
}
标签:Sequence,蔚来,rep,多校,括号,Longrightarrow,longrightarrow,dp,MOD 来源: https://www.cnblogs.com/xhy666/p/16519344.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。