Codeforces 629C Famil Door and Brackets

阅读: 评论:0

Codeforces 629C Famil Door and Brackets

Codeforces 629C Famil Door and Brackets


合法的序列满足:

  1. () 的个数相同。
  2. 对于每个前缀,有左括号的个数>=右括号的个数

所以思路是,用 dp[i][j] 表示长度为长度为i,且左括号比右括号多j的串的个数。递推式可以写为:

dp[i][0] = dp[i-1][1]
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#define fi first
#define se second
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
//head
LL dp[2005][2005]={0};
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;void init(int k)
{dp[0][0] = 1;for(int i=1; i<=k; i++){dp[i][0] = dp[i-1][1];for(int j=1; j<=k; j++)dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1]) % mod;}
}int main()
{int n,m;while(scanf("%d%d",&n,&m)!=EOF){string s;cin>>s;init(n-m);int pre = -INF;//在p中要多加入pre个前括号int suf;//在s中有suf个多余的前括号int sum1=0,sum2=0;for(int i=0; i<m; i++){if(s[i]==')'){sum1++;sum2--;}else{sum1--;sum2++;}pre = max(sum1, pre);}suf = sum2;LL ans = 0;for(int i=0; i<=n-m; i++)for(int j=max(0, pre); j<=n-m; j++){int k = j+suf;//在p中加的前括号抵消了s中的部分后括号if(k <= n-m){ans += (dp[i][j] * dp[n-m-i][k]) % mod;//dp[n-m-i][k] = dp[n-m-i][-k],对称ans %= mod;}}printf("%I64dn", ans);}
}

本文发布于:2024-02-04 05:07:46,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170699761752333.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Codeforces   Famil   Brackets   Door
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23