合法括號子段 51Nod - 1791
阿新 • • 發佈:2018-11-23
http://www.51nod.com/Challenge/Problem.html#!#problemId=1791
先用棧找出每個右括號向左能匹配多遠 這樣是找出了所有獨立的合法序列 然後再算上兩兩拼接而成的新合法序列 dp陣列維護一下就好
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e6+10; stack <int> stk; ll dp[maxn]; int pos[maxn]; int n; char ch[maxn]; void init() { int i,p; while(!stk.empty()) stk.pop(); for(i=1;i<=n;i++) pos[i]=-1; for(i=1;i<=n;i++){ if(ch[i]=='(') stk.push(i); else{ if(!stk.empty()){ p=stk.top(); stk.pop(); pos[i]=p-1; } } } } ll solve() { ll res; int i; for(i=1;i<=n;i++) dp[i]=0; res=0; for(i=1;i<=n;i++){ if(pos[i]!=-1) dp[i]=dp[pos[i]]+1; res+=dp[i]; } return res; } int main() { int t; scanf("%d",&t); while(t--){ scanf("%s",ch+1); n=strlen(ch+1); init(); printf("%lld\n",solve()); } return 0; }