2026年9月GESP真题及题解(C++七级):括号序列

2026年9月GESP真题及题解(C++七级):括号序列

题目描述

对于字符串 S S S 与 T T T,如果从 S S S 中删除任意多个字符可以得到 T T T,那么 T T T 是 S S S 的子序列。换言之, T T T 是选取 S S S 中的若干字符按下标顺序连接而成的。两个子序列不同当且仅当所选取的下标不同。

例如 sun 是 sequence 的子序列,因为从 sequence 中删除 eq、e 和 ce 可以得到 sun;sequence 有 2 8 2^8 28 个不同的子序列,其中有空字符串,也有三个不同的子序列 e,因为 sequence 的第 2 , 5 , 8 2,5,8 2,5,8 个字符都为 e,分别保留这三个字符得到的子序列是不同的。

对于字符串 S S S,如果 S S S 满足以下条件那么 S S S 是合法括号序列:

  • S S S 是空字符串,或者
  • S S S 可由 (、合法括号序列、) 三者连接得到,或者
  • S S S 可由两个合法括号序列连接得到。

例如 ()、()()、(()) 和 (()()) 都是合法括号序列。但是 (()、)( 不是合法括号序列。

给定一个长度为 n n n 的仅包含 ( 与 ) 的字符串 S S S。请你求出 S S S 所有 2 n 2^n 2n 个子序列中有多少个合法括号序列。由于答案可能很大,请你输出答案对 10 9 10^9 109 取模的结果。

例如, S S S 为 ))(()( 时共有 3 3 3 个子序列是合法括号序列,分别为空字符串与两个不同的子序列 ()。

输入格式

第一行,一个正整数 n n n,表示字符串 S S S 的长度。

第二行,长度为 n n n 的仅包含 ( 与 ) 的字符串 S S S。

输出格式

输出一行,一个整数,表示 S S S 的合法括号子序列的数量对 10 9 10^9 109 取模的结果。

输入输出样例 1
输入 1
复制代码
6
))(()(
输出 1
复制代码
3
输入输出样例 2
输入 2
复制代码
34
((((((((((((((((()))))))))))))))))
输出 2
复制代码
333606220
说明/提示

对于 40 % 40\% 40% 的测试点,保证 1 ≤ n ≤ 400 1\le n\le 400 1≤n≤400。

对于所有测试点,保证 1 ≤ n ≤ 2000 1\le n\le 2000 1≤n≤2000。

思路分析

合法括号序列等价于:

  • 任意前缀中,左括号数量不少于右括号数量;
  • 最终左右括号数量相等。

把左右括号数量差记为"平衡值":

  • 遇到 (,平衡值加一;
  • 遇到 ),平衡值减一;
  • 合法括号序列要求任意时刻平衡值不小于 0,最终平衡值为 0。

由于题目统计的是"按下标选取不同"的子序列,因此对 S 中每个字符只需要考虑"选"或"不选"两种决策。每个选法唯一对应一个子序列,即使字符相同,只要下标不同就算不同子序列。

设 f[j] 表示当前处理到某个位置时,已经选出的子序列平衡值为 j,且过程中没有出现平衡值小于 0 的方案数。初始时选择空子序列,所以 f[0] = 1。

处理当前字符 c 时,用新数组 g 表示加入这个字符后的状态:

  • 不选 c:g[j] += f[j];
  • 若 c == '(',选它:g[j+1] += f[j];
  • 若 c == ')',选它且 j > 0:g[j-1] += f[j]。

处理完所有字符后,f[0] 就是所有合法括号子序列数量,其中包含空字符串。

时间复杂度为 O(n^2),空间复杂度为 O(n),可以轻松通过 n <= 2000。

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int M=1000000000;//模数
int n;
string s;

int main(){
    cin>>n;
    cin>>s;
    vector<int> f(n+1,0),g(n+1,0);//旧状态和新状态
    f[0]=1;//空串
    for(int i=0;i<n;i++){//处理第i个字符
        fill(g.begin(),g.end(),0);//清空新状态
        for(int j=0;j<=i;j++){//当前平衡值
            if(f[j]==0)continue;//无方案
            g[j]=(g[j]+f[j])%M;//不选
            if(s[i]=='(')g[j+1]=(g[j+1]+f[j])%M;//选左括号
            else if(j>0)g[j-1]=(g[j-1]+f[j])%M;//选右括号
        }
        f.swap(g);//滚动数组
    }
    cout<<f[0]<<'\n';//答案
    return 0;
}

功能分析

该程序使用动态规划统计字符串 S 所有子序列中合法括号序列的数量。

f[j] 表示当前平衡值为 j 且任意前缀平衡值不小于 0 的子序列方案数。每读入一个字符,分别考虑不选、选左括号、选右括号三种转移。最终 f[0] 即为所有合法括号子序列数量,包括空字符串。

算法时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O(n)。


各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:

https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:

https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:

https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:

https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
Tisfy8 天前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
孤独的Bochi8 天前
# [CSP-S 2026] 迁徙 / migrate 题解
题解
Tisfy8 天前
LeetCode 3665.统计镜子反射路径数目:三个动态规划数组
leetcode·动态规划·代理模式·题解
漂流瓶jz9 天前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
王老师青少年编程9 天前
2026年信奥赛c++普及组csp-j第二轮复赛真题
c++·真题·csp·信奥赛
lvwangshu12 天前
P15569 [COCI 2025/2026 #5] 结构 / Struktura 题解
矩阵·题解·dp·推导题·矩阵加速
lvwangshu15 天前
T3 涂鸦带师 题解
题解·贪心·倍增·技巧·思维好题·断环成链
王老师青少年编程17 天前
2025年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
Tisfy17 天前
LeetCode 3644.排序排列:不对则与(脑筋急转弯)
数据结构·算法·leetcode·题解·位运算
lvwangshu18 天前
P8981 「DROI」Round 1 距离 题解
动态规划·图论·题解·dp·树形dp·技巧·换根dp·性质题·思维好题