Luogu P1944 最长括号匹配

Luogu P1944 最长括号匹配

显然是一道 DP。

设 $f_i$ 为以第 $i$ 位结尾的最长括号匹配子串的长度。

则当 s[i-f[i-1]-1]s[i] 匹配时,$f_i=f_{i-1}+2+f_{i-f_{i-1}-2}$。$f_{i-f_{i-1}-2}$ 表示这个匹配之前可能存在的一个匹配的长度。

特别注意的是,不要在 for 循环里写 strlen(s),这样每次循环的时候都要计算一次,会有三个点超时。

代码实现如下:

#include<bits/stdc++.h>
#define N 1000010

int ans,pos;
int f[N];
char s[N];

namespace WalkerV {
	void Read() {
		scanf("%s",s);
		return;
	}

	void Solve() {
		int len=strlen(s);
		for(int i=0;i<len;i++) {
			if(s[i]==')') {
				if(s[i-f[i-1]-1]=='(') {
					f[i]=f[i-1]+2+f[i-f[i-1]-2];
				}
			}
			if(s[i]==']') {
				if(s[i-f[i-1]-1]=='[') {
					f[i]=f[i-1]+2+f[i-f[i-1]-2];
				}
			}
			if(ans<f[i]) {
				ans=f[i];
				pos=i;
			}
			//printf("f[%d]:%d\n",i,f[i]);
		}
		return;
	}

	void Print() {
		//printf("%d %d\n",ans,pos);
		for(int i=pos-ans+1;i<=pos;i++) {
			printf("%c",s[i]);
		}
		printf("\n");
		return;
	}
}

int main()
{
	WalkerV::Read();
	WalkerV::Solve();
	WalkerV::Print();
	return 0;
}
posted @ 2021-10-07 21:43  WalkerV  阅读(76)  评论(0编辑  收藏  举报