首页 > 其他分享 >关于求合法括号子序列个数

关于求合法括号子序列个数

时间:2024-09-09 09:47:52浏览次数:1  
标签:匹配 个数 pos 合法 括号 序列 贡献

求合法括号子序列个数

发了近半天时间都没人发现里面的致命错误() 还好我悄咪咪改了

题意

背景

合法括号串的定义如下:

  1. () 是合法括号串。
  2. 如果 A 是合法括号串,则 (A) 是合法括号串。
  3. 如果 AB 是合法括号串,则 AB 是合法括号串。

子串不同的子串的定义如下:

  1. 字符串 S 的子串是 S连续的任意个字符组成的字符串。S 的子串可用起始位置 \(l\) 与终止位置 \(r\) 来表示,记为 \(S (l, r)\)(\(1 \leq l \leq r \leq |S |\),\(|S |\) 表示 S 的长度)。
  2. S 的两个子串视作不同当且仅当它们在 S 中的位置不同,即 \(l\) 不同或 \(r\) 不同。

题目

给出一个括号串 \(s\)(其不一定是合法括号串),问 \(s\) 中有多少个互不相同的子串合法括号串

样例

样例输入

(()()

样例输出

3

分析

观察序列1:

()()()

\(pos = 2\) 的时候,对答案的贡献值为 \(1\) 。

\(pos = 4\) 的时候,本身 \([3, 4]\) 就有一个满足要求的括号序列,再合并上前面的成为 \([1, 4]\) ,于是对答案的贡献值就为 \(2\) ,再加上前面 \([1, 2]\) 本身有的括号序列,总共为 \(3\)。

\(pos = 6\) 时,总共的贡献值为 \(3\) ,加上前面的有 \(3 + 3 = 6\) 种。其他位置均没有贡献(左括号没有贡献值)。

总之,\(pos\) 为 \(1 \sim 6\) 时对答案的贡献分别为 \(0, 1, 0, 2, 0, 3\) ,合并后的总答案为 \(0, 1, 1, 3, 3, 6\) 。


观察序列2:

())()

\(pos = 2\) 时,对答案贡献为 \(1\) 。

\(pos = 3\) 时,由于不满足成匹配的括号序列,所以没有贡献(我们只看右括号的贡献值)。

\(pos = 5\) 时,由于 \(pos = 3\) 时多了一个后括号,所以 \([1, 3]\) 不匹配,导致 \([1, 5]\) 成不了一个匹配的括号序列,所以对答案的贡献仍为 \(1\)

\(pos\) 为 \(1 \sim 5\) 时对答案的贡献分别为 \(0, 1, 0, 0, 1\) ,合并后的总答案为 \(0, 1, 1, 1, 2\) 。


观察序列3:

()(())

\(pos = 2\) 时,贡献为 \(1\) 。

\(pos = 5\) 时,由于 \(pos = 3\) 是在中间断开,所以 \([1, 5]\) 不能匹配,所以贡献仍为 \(1\) 。

\(pos = 6\) 时,我们发现 \([1, 2]\) 是匹配的。故 \([1, 2], [3, 6]\) 能合成一个匹配的序列,所以对答案贡献为 \(2\) 。

\(pos\) 为 \(1 \sim 6\) 时对答案的贡献分别为 \(0, 1, 0, 0, 1, 2\) ,合并后的总答案为 \(0, 1, 1, 1, 2, 4\) 。


可以发现,一个后括号如果能匹配一个前括号,假设这个前括号的前1位同样有一个已经匹配了的后括号,那么我们就可以把当前的匹配括号序列和之前的匹配括号序列合并。当前的这个后括号的贡献值,其实就等于前面那个后括号的贡献值 + 1。

Elaina's Code

int sum=0,tot[N];
string s;
stack<int> sta;
signed main(){
	cin>>s;
	for(int i=0;i<s.size();i++){
		if(s[i]=='(') sta.push(i);
		if(s[i]==')'){
			if(!sta.empty()){
				int l=sta.top();
				sta.pop();
				tot[i]=tot[l-1]+1;
			}
		}
		sum+=tot[i];
	}
	cout<<sum;
	return Elaina;
}

标签:匹配,个数,pos,合法,括号,序列,贡献
From: https://www.cnblogs.com/Elaina-0/p/18403043

相关文章

  • 51nod 1791 合法括号子段
    51nod1791原题链接因为在括号串固定的情况下,括号的匹配是固定不变的。所以对左括号进行匹配,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程ans[i]=ans[p[i]+1]+1,然后再从后先前一遍求和即可。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconst......
  • 手撕Python之序列类型
    1.列表---list索引的使用当我们有一个数据的时候,我们怎么将这个数据存储到程序呢?我们定义一个变量,将数据存储在变量中那么如果有100个数据呢?要定义100个变量吗?我们是可以用列表这个东西进行多个数据的存放列表的定义:[]空列表:[]列表:[元素1,元素2,元素3]列表中的内容......
  • 392. 判断子序列(leetcode)
    https://leetcode.cn/problems/is-subsequence/description/classSolution{publicbooleanisSubsequence(Strings,Stringt){//依据题意,可以判断是求最长公共子序列的特殊情况//f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+1)//f[1]......
  • 时间序列结构变化分析:Python实现时间序列变化点检测
    平稳性是时间序列分析与预测的核心概念。在平稳条件下,时间序列的统计特性(如均值)在时间维度上保持不变,仅存在随机波动。但是实际数据集中很少观察到完全的平稳性。时间序列通常会经历结构性断裂或变化。这些变化会引入非平稳性,从而改变时间序列的整体分布,这些标志着变化开始的时间......
  • LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现N*K时间复杂度
    3177.求出最长好子序列II题目链接题目描述给你一个整数数组nums和一个非负整数k。如果一个整数序列seq满足在下标范围[0,seq.length-2]中最多只有k个下标i满足seq[i]!=seq[i+1],那么我们称这个整数序列为好序列。请你返回nums中好子序列的最长长度......
  • LCP 485. 最大连续 1 的个数[lleetcode -11]
    从今天起,我们的算法开始研究搜索,首先就是DFS深度优先搜索(depth-firstseach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进......
  • 1.有 1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?
    【程序1】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?#1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去#掉不满足条件的排列。#2.程序源代码:count=0results=[]foriinrange(1,5):forjinran......
  • Java反序列化漏洞-TemplatesImpl利用链分析
    目录一、前言二、正文1.寻找利用链2.构造POC2.1生成字节码2.2加载字节码1)getTransletInstance2)defineTransletClasses2.3创建实例3.完整POC三、参考文章一、前言java.lang.ClassLoader#defineClassdefineClass可以加载字节码,但由于defineClass的作用域是protected,所以攻......
  • 【SpringBoot实用小知识】JSON序列化返回结果时出现的幽灵成员
    幽灵成员问题的解决前言debug过程结论及解决方式1.更改方法名称2.为方法加上@JsonIgnore注解前言这是一个很令人无语的问题在最近写代码时发现一个问题就是有时候在测试接口的时候发现返回结果中出现了一些本不该出现的字段甚至有时候还报错信息如下Writing......
  • 代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II
    代码随想录刷题day25丨491.递增子序列,46.全排列,47.全排列II1.题目1.1递增子序列题目链接:491.非递减子序列-力扣(LeetCode)视频讲解:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibili文档讲解:https://programmercarl.com/0491.%E9%80......