Luogu P8007
Upd.2022.2.3 代码写的太烂,删了(
这题如果不仔细分析的话,很容易被当成DP白白浪费很多时间(就像我)。
首先根据题意,可以认为左右括号是一种相互“抵消”的关系:
对于每个左括号,它右面总要有且仅有一个对应的右括号与其配对,才能使其成为一个合法括号序列。
在已知序列不无限循环的时候,为了使一个序列为合法括号序列,我们需要保证的条件有:
- 左右括号数目相等。
- 每个右括号出现时,必须保证它左边有可以和它配对的左括号。
如果还是不理解,可以看下代码:
bool check(){
int l=0;//统计左右括号之差
for(int i=1;i<=n;i++){
if(s[i]=='(')l++;
else{
if(l==0)return 0;//保证右括号左边有可以和它配对的左括号
else l--;
}
}
return l==0;//保证左右括号数目相等
}
但是在无限循环的情况下,我们只需要保证左右括号相等即可,证明如下:
首先如果不相等,它一定不是合法括号序列,因为这样即使无限循环下去,也一定存在无法配对的括号,这是显然的。
在左右括号相等时,序列不合法的情况只有一个:即当一个右括号出现时,左边所有左括号都配对完了,没有剩下和它配对的了,例如 (()())))((
。
由于左右括号数目相等,无法配对的右括号一定和无法配对的左括号数目相等。
那么,如果将无法配对的右括号都搬到无法配对的左括号右边,这个序列就一定是一个合法括号序列了。
比如,对于 (()())))((
,我们如果将 (()())))
都搬到序列右边,使无法配对的右括号和无法配对的左括号配上对,得到的 (((()())))
就一定是一个合法括号序列。
而题目中的“无限循环”正帮我们实现了这个“搬”的过程。
证毕。
那么这题的任务就变成了“求出所有问号的填法中能使左右括号数目相等的方案数
由于左右括号数目之和等于
令已知的左括号数目为
那么剩下的就是老生常谈的求组合数了,由于
代码太丑,略了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?