web刷題總結(未完.......)
阿新 • • 發佈:2021-10-02
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; }