P1944 最长括号匹配
可以直接用栈模拟,把匹配好的标记一下, 最后找到最长的匹配输出即可。
如果是要求最长的长度的题那么只需要求数就行了,没必要把原序列真的按照题意改变
如果要求序列,那么只需要按照题意把答案标记出来输出即可,没必要真的一段一段找。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<stack>
#define ls (p<<1)
#define rs (p<<1|1)
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#define over(i,s,t) for(register int i = s;i <= t;++i)
#define lver(i,t,s) for(register int i = t;i >= s;--i)
//#define int __int128
#define lowbit(p) p&(-p)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1000100;
const int mod = 1e4+7;
const double EPS = 1e-10;
const int base = 131;
int cnt,l,ansl,ansr;
string str;
int stk[N][2];
int n,m,top;
bool vis[N];
int main()
{
cin>>str;
int len = str.length();
over(i,0,len-1){
char ch =str[i];
if((ch == ']'&&stk[top][0] == '[')||(ch == ')'&&stk[top][0] == '('))vis[stk[top--][1]] = vis[i] = 1;
else stk[++top][0] = ch,stk[top][1] = i;
}
int ans = 0;
over(i,0,len-1)
if(!vis[i])cnt = 0,l = i+1;
else {
cnt++;
if(cnt >ans)
ans = cnt,ansl = l,ansr = i;
}
over(i,ansl,ansr)putchar(str[i]);
return 0;
}
大佬们都是用DP做的:
//我们可以用dp【i】表示以i结尾的最长合法序列长度
//那么对于每一个元素,只需考虑它的上一个元素的长度即可
//就有dp方程:dp[i]=dp[i-1]+2+dp[i-2-dp[i-1]];
//以下是代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
char st[maxn];
int ans;
int dp[maxn];
int main()
{
scanf("%s",st+1);int len=strlen(st+1);
for(int i=1;i<=len;i++)
{
if(st[i]=='(' || st[i]=='[')continue;
if(st[i]==')' || st[i]==']')
{
if((st[i]==')' && st[i-1-dp[i-1]]=='(') || (st[i]==']' && st[i-1-dp[i-1]]=='['))
{
dp[i]=dp[i-1]+2+dp[i-2-dp[i-1]];
ans=max(ans,dp[i]);
}
}
}
for(int i=1;i<=len;i++)
if(dp[i]==ans)
{
for(int j=i-ans+1;j<=i;j++)printf("%c",st[j]); return 0;
}
}
//https://www.luogu.com.cn/blog/user25365/solution-p1944
注:如果您通过本文,有(qi)用(guai)的知识增加了,请您点个赞再离开,如果不嫌弃的话,点个关注再走吧,日更博主每天在线答疑 ! 当然,也非常欢迎您能在讨论区指出此文的不足处,作者会及时对文章加以修正 !如果有任何问题,欢迎评论,非常乐意为您解答!( •̀ ω •́ )✧