清北学堂

清北学堂 11.23

A

给定一个括号串,求最少进行多少次“交换两个相邻的字符"能使该括号串合法

空串是合法括号串

如果A是合法括号串,则(A)是合法括号串

如果A,B是合法括号串,则A,B是合法括号串

肯定先要满足前面的不匹配的右括号,但这样会对后面移动的距离产生一定的影响。

比如))((

  1. )()(
  2. ())(
  3. ()()

其次如果前面已经匹配的括号对可以直接抵消,不会对后面产生影响

这样大概率就可以线性计算了。

考虑如何计算交换次数:

官方说把他看成一个折线图,规定左括号为斜向上,右括号为斜向下。如果纵坐标小于0,那么

画出括号序列的折线图。
答案即为 ∑⌈max⁡(−pi,0)/2⌉ 。其中 pi 表示横坐标为 i 时的纵坐标。
为什么?
我们考虑一次交换左右两个括号的实质。
以左边是右括号为例,那么这个过程等价于把 pi+=2 。
那么答案显然是上述式子。
时间复杂度 O(n),空间复杂度 O(1) 。

但我很奇怪为什么要有(-pi,0)/2

这样不是好理解多了吗

#include<bits/stdc++.h>
using namespace std;
string s;
#define rt register int 
int n;
long long res,ans;
inline string sread(){
	string ans;
	char ch=getchar();
	while(ch==' '||ch=='\n'||ch=='\t') ch=getchar();
	while(ch!=' '&&ch!='\n'&&ch!='\t') ans+=ch,ch=getchar();
	return ans;
}
int main()
{
	s=sread();
	n=s.length();
	for(rt i=0;i<n;++i)
	{
		if(s[i]=='(')
		{
			if(res<0)ans+=abs(res);
			res+=1;
		}else res--;
	}
	cout<<ans<<endl;
} 
posted @ 2022-11-23 15:30  zyc_xianyu  阅读(67)  评论(0编辑  收藏  举报