首页 > 其他分享 >P7914 [CSP-S 2021] 括号序列

P7914 [CSP-S 2021] 括号序列

时间:2022-10-22 21:22:08浏览次数:55  
标签:ast int text P7914 括号 字符串 2021 序列 CSP

简要题意

给定 \(k\),定义 “超级括号序列”(简称括号序列,下同) 字符串为:

  • 仅由 ( ) * 三种字符组成。
  • 下面令 \(S\) 为不超过 \(k\) 个 \(\ast\) 字符拼接而成的字符串(\(S\) 可以为空字符串)。
  • \(\text{(S)}\) 是括号序列。
  • 如果 \(A\) 是括号序列,\(\text{(AS)},\text{(SA)}\) 都是括号序列。
  • 如果 \(A,B\) 是括号序列,则 \(\text{ASB}\) 是括号序列。
  • 特别的,空字符串不是括号序列。

例如,若 \(k = 3\),则字符串 \(\text{((**()*(*))*)(***)}\) 是括号序列,但字符串 \(\text{*()}\)、\(\text{(*()*)}\)、\(\text{((**))*)}\)、\(\text{(****(*))}\) 均不是。

给你一个长度为 \(n\) 的括号序列 \(s\),有的字符已经确定,有的字符尚未确定(用 \(\text{?}\) 替代)。求该字符串将所有尚未确定的字符一一确定的方法,使得得到的字符串是一个括号序列?对 \(10^{9}+7\) 取模。

对于 \(100 \%\) 的数据,\(1 \le k \le n \le 500\)。

思路

非常神仙的区间 DP 题。

状态设计

先设状态:

  • \(f[l][r][0]\) 为 \([l,r]\) 为 \(S\) 型字符串的个数。如 ********
  • \(f[l][r][1]\) 为 \([l,r]\) 为被匹配的括号包裹的字符串个数。如 (*(*(*))*)
  • \(f[l][r][2]\) 为 \([l,r]\) 为以括号序列开头,\(\ast\) 结尾的字符串个数。如 (*(*)*)***(*)*
  • \(f[l][r][3]\) 为 \([l,r]\) 为以括号序列开头与结尾的字符串个数,包含 \(f[l][r][2]\)。
  • \(f[l][r][4]\) 为 \([l,r]\) 为以括号序列结尾,\(\ast\) 开头的字符串个数,如 ****(*(***))
  • \(f[l][r][5]\) 为 \([l,r]\) 为以 \(\ast\) 开头或结尾的个数,包含 \(f[l][r][0]\)。

状态转移

\[f[l][r][0]=\left\{ \begin{aligned} & f[l][r-1][0] & \operatorname{ast}(r)\\ & 0 & \text{otherwise} \end{aligned} \right. \]

解释:\(\operatorname{ast}(r)\) 指 \(s_r\) 可能为 \(\ast\)。如果不是 \(\ast\) 自然没有了。

\[f[l][r][1]=\left\{ \begin{aligned} & (f[l+1][r-1][0]+f[l+1][r-1][2]+f[l+1][r-1][3]+f[l+1][r-1][4])& \operatorname{match(l,r)} \\ & 0 & \text{otherwise} \end{aligned} \right. \]

解释:\(\operatorname{match}(l,r)\) 为 \(s_l,s_r\) 可能括号匹配。加括号的时候,除了两边都是 \(\ast\) 且中间有括号序列外,其他都可以。

\[\begin{aligned} &f[l][r][2]=\sum_{i=l}^{r-1}f[l][i][3]\cdot f[i+1][r][0] \\ &f[l][r][3]=(\sum_{i=l}^{r}(f[i+1][r]\cdot (f[l][i][2]+f[l][i][3]))+f[l][r][1]) \\ &f[l][r][4]=\sum_{i=l}^{r}f[i+1][r][1]\cdot (f[l][i][4]+f[l][i][5]) \\ &f[l][r][5]=(\sum_{i=l}^{r}f[l][i][4]\cdot f[i+1][r][0])+f[l][r][0] \end{aligned} \]

  • \(f[l][r][2]\) 中是括号序列开头(3)接 \(\ast\)(0)
  • \(f[l][r][3]\) 可以是 2,3 开头,必须是 0 结尾
  • \(f[l][r][4]\) 可以是4,5 开头,必须是 1 结尾
  • \(f[l][r][5]\) 可以是4 开头,0 结尾。

最后答案就是 \(f[1][n][3]\)。

时间复杂度 \(O(n^3)\)。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int f[505][505][10];
char s[505];
int n,k;
const int MOD = 1e9+7;

inline bool is_star(int pos){
	return (s[pos]=='*'||s[pos]=='?');
}
inline bool is_left_bracket(int pos){
	return (s[pos]=='('||s[pos]=='?');
}
inline bool is_right_bracket(int pos){
	return (s[pos]==')'||s[pos]=='?');
}
inline bool is_brackets_matched(int left,int right){
	return is_left_bracket(left)&&is_right_bracket(right);
}
int m(int x){return (x%MOD+MOD)%MOD;}
void M(int &x){x=m(x);}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>k;
	cin>>(s+1);
	for(int i=1;i<=n;i++){
		f[i][i-1][0]=1;
	}
	for(int length=1;length<=n;length++){
		for(int l=1,r=length;l<=n&&r<=n;l++,r++){
			// 处理情况 0
			if(length<=k && f[l][r-1][0] && is_star(r))f[l][r][0]=1;
			else f[l][r][0]=0;
			// 处理情况 1
			if(length>1 && is_brackets_matched(l,r)){
				f[l][r][1]=m(f[l+1][r-1][0]+f[l+1][r-1][2]+f[l+1][r-1][3]+f[l+1][r-1][4]);
			}
			// 处理情况 2
			if(length>1){
				for(int i=l;i<r;i++){
					f[l][r][2] += m(f[l][i][3]*f[i+1][r][0]);
					M(f[l][r][2]);
				}
			}
			// 处理情况 3
			if(length>1){
				for(int i=l;i<r;i++){
					f[l][r][3] += m(m(f[l][i][2]+f[l][i][3])*f[i+1][r][1]);
					M(f[l][r][3]);
				}
			}
			f[l][r][3] += f[l][r][1];M(f[l][r][3]);
			// 处理情况 4
			if(length>1){
				for(int i=l;i<r;i++){
					f[l][r][4] += m(m(f[l][i][4]+f[l][i][5])*f[i+1][r][1]);
					M(f[l][r][4]);
				}
			}
			// 处理情况 5
			if(length>1){
				for(int i=l;i<r;i++){
					f[l][r][5] += m(f[l][i][4]*f[i+1][r][0]);
					M(f[l][r][5]);
				}
			}
			f[l][r][5]+=f[l][r][0];M(f[l][r][5]);
		}
	}
	cout<<m(f[1][n][3]);
	return 0;
}

标签:ast,int,text,P7914,括号,字符串,2021,序列,CSP
From: https://www.cnblogs.com/zheyuanxie/p/p7914.html

相关文章

  • 2022/10/22 CSP赛前隔离时的模拟赛 1/3
    T1T2使用一种类似于摩尔投票法的东西(Keven_He说像,我不太觉得):将所有人分为两队,设第一队的总攻击力为\(a\),第二队的总攻击力为\(b\)。不妨设\(a\leb\),求\(\min(b-......
  • CSP-S模拟20
    T1.归隐签到题吧算是。看到数据范围直接来推结论。先把对数去掉,就变成了指数项的加法。容易发现\(a_i=3a_{i-1}+1\),除了两侧的数,其它的贡献都翻了一倍放在中间。然后用等......
  • 2022-2023-1 20211319《信息安全专业导论》第八周学习总结
    2022-2023-120211319《信息安全专业导论》第八周学习总结2021-2022-120211326《信息安全专业导论》第八周学习总结作业信息加入云班课,参考本周学习资源自学教材......
  • Linux下matalb2021a和2022a无法启动simulink的解决方案之一
    提示错误类似:bin/glnxa64/MATLABWindow:symbollookuperror:somelibrary:undefinedsymbol:FT_Get_Var_Blend_Coordinatesor:bin/glnxa64/MATLABWindow:symbollo......
  • 小孩的游戏 - 2021数据结构 排序和选择实验题
    小孩的游戏-2021数据结构排序和选择实验题pre做都做了,干脆发上来算了:D题目分析算法与数据结构实验题5.18小孩的游戏★实验任务一群小孩子在玩游戏,游戏......
  • CSP 2022备战 STL
    只要不上网课,大概是最后一篇?一.vectorvector,中文名容器,它可以容纳许多数据类型头文件:#include<vector>定义:vector<数据类型>变量名;也可以vector<数据类型>变量名(数......
  • 第二十三章 CSP Session 管理 - 身份验证共享策略
    第二十三章CSPSession管理-身份验证共享策略本节介绍如何通过两种方式创建一组应用程序以作为一个组工作:共享认证:如果应用程序不共享认证,用户必须分别登录到被另一......
  • CVE-2021-23132:Joomla远程代码执行漏洞
    0x00概述:Joomla是一套知名的内容管理系统,使用的是php语言和mysql数据库开发的,可以在各大系统场景进行使用。影响版本:Joomla3.0.0~3.9.240x01复现过程:打开搭建好的环境......
  • 2021-2022:时间戳
    转载:https://www.cnblogs.com/imyalost/p/15732730.html 博客今年博客更新的频次还行,一方面是工作上接触了很多新的领域,有很多的实践经验;另一方面,在新的公司,有部分工作......
  • P7914 括号序列
    \(\rmP7914\)[CSP2021]括号序列加深理解做题简记。这里觉得第一篇题解的做法是最优秀的,因为这才是真正的dp强调的不重不漏。这个做法只设了一个dp数组,应该跟其他设......