CF629C题解

CF629C

这里更容易进入且有翻译

题意

给定长度为 m 的仅含 () 的字符串,为其左右补上两个字符串使其达到指定长度 n 且合法, 需补足字符串合计长度 nm 满足 nm2000

解析

字符串合法条件为:

左右括号总数相等;

从左数起在任意位置上左括号数量不小于右括号数量。

首先思考下左侧的合法状况,设 fi,j1 为前 i 个字符使用了 j( 时的方案数,有 f0,01=1,得到状态转移方程为:

fi,j1=fi1,j11+fi1,j1

然后思考下另一侧,题意表明左右括号总数相等,且从左数起一定有左括号数 l 不小于右括号数 r,即

lr

可化成

n2ln2r

即从右数起在任意位置上右括号数量不小于左括号数量。由此,可设 fp,q2 为从右数起前 p 个字符使用了 q) 时的方案数,状态转移方程同上。

最后,枚举左右状态并利用乘法原理即可算出答案,设需补足的右括号共为 tr 个,对于任意状态下都有 p=nmiq=tr(ij)

代码

#include<bits/stdc++.h>
#define LL long long 

using namespace std;

vector<vector<LL> > dp1(2005, vector<LL>(2005, 0)), dp2(2005, vector<LL>(2005, 0));
LL mod = 1000000007;
//要开long long,不然#4可能会炸精度

signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	LL n, m, tl = 0, tr, nl = 0, nr = 0, ml = 0, mr = 0, ans = 0;
	string s;
	cin >> n >> m;
	getline(cin, s);
	getline(cin, s);

	for (int i = 0; i < m; i++)
	{
		tl += s[i] == '(';
		nl += 2 * (s[i] == ')') - 1; //计算当前右左括号数量差
		ml = max(ml, nl); //存储最大差值
						  //左方插入字符串左右括号数量差至少达到ml
	}
	//反向遍历一次计算左右括号数量差值,作用同上
	for (int i = m - 1; i > -1; i--)
	{
		nr += 2 * (s[i] == '(') - 1;
		mr = max(mr, nr);
	}

	if (tl > n / 2 || m - tl > n / 2 || n & 1)
	{
		//将完全不合法的情况直接排除
		cout << "0";
		return 0;
	}
	tl = n / 2 - tl;
	tr = n - m - tl;
	//tl和tl分别表示外部插入字符串总共需要的左右括号数量

	//计算左侧合法情况
	dp1[0][0] = 1;
	for (LL i = 1; i <= min(n - m, tl * 2); i++)
		for (LL j = 0; j <= min(i, tl); j++)
			if (i - j <= j && i - j <= tr)
				dp1[i][j] = (dp1[i - 1][j - 1] + dp1[i - 1][j]) % mod;

	//计算右侧合法情况
	dp2[0][0] = 1;
	for (LL i = 1; i <= min(n - m, tr * 2); i++)
		for (LL j = 0; j <= min(i, tr); j++)
			if (i - j <= j && i - j <= tl)
				dp2[i][j] = (dp2[i - 1][j - 1] + dp2[i - 1][j]) % mod;

	//乘法原理计算答案
	for (int i = 0; i <= n - m; i++)
		for (int j = 0; j <= i; j++)
			if (j - (i - j) >= ml && tr - (i - j) - (tl - j) >= mr) //判断左右侧的左右括号数是否达到要求
				ans = (ans + dp1[i][j] * dp2[n - m - i][tr - i + j]) % mod;

	cout << ans;
}

最后祝各位顺利AC。 >w<

posted @   OEAiHAN  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示