【日常刷題】最長括號匹配DP
阿新 • • 發佈:2018-11-08
最長括號匹配
這道題目看似可以使用棧來做,實則用DP可以更加簡單。
我們設
為以第i位結尾的可以匹配的最大長度。
對於每一個第
位,如果需要存在合法序列必須滿足兩個條件
1.是左括號
2.必須和其有邊的字元組成一個序列
事實上對於第一個條件我們只要簡單的判斷,而對於第二個條件就和我們的決策有關。
而對於轉移方程f[i],只要當前的這個字元
和以
位起點構成串的有邊匹配,就說明能夠成立一個合法的串。如果列出轉移方程,就是:
對於條件3,我們只要繼續累加
即可。
CODE
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2000000
int MAX=0,st=0,f[MAXN];
char s[MAXN];;
int main()
{
cin>>s;
int len=strlen(s);
for (int i=len-1;i>=0;--i)
{
if (s[i]==')' || s[i]==']') continue;//右括號不合法
if ((s[i]=='(' && s[i+f[i+1]+1]==')') || (s[i]=='[' && s[i+f[i+1]+1]==']'))//存在對頂的字串
{
f[i]=f[i+1]+2;//上一個決策加上新的收尾
f[i]+=f[i+f[i]];//滿足條件3,即多個不同的串進行累加
if (f[i]>=MAX) MAX=f[i],st=i;
}
}
for (int i=0;i<MAX;i++) cout<<s[st+i];
return 0;
}