51nod 1791 合法括号子段

51nod 1791 原题链接

因为在括号串固定的情况下,括号的匹配是固定不变的。所以对左括号进行匹配,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程 ans[i]=ans[p[i]+1]+1,然后再从后先前一遍求和即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1100005;
char c[N];
ll ans[N];
int p[N];
int s[N];
int top;
int t;

int main() { 
    ios::sync_with_stdio(false);
    cin>>t;
    
    while(t--){
    	cin>>(c+1);
    	int n=strlen(c+1),top=0;
    	
    	for(int i=1;i<=n;i++){
    		p[i]=-1;
		}
    	
    	for(int i=1;i<=n;i++){
    		if(c[i]=='('){
    			s[++top]=i;
			}
			else if(top){
				p[s[top--]]=i;
			}
		}
		ll sum=0;
		for(int i=n;i>=1;i--){
			if(p[i]==-1){
				ans[i]=0;
			}
			else{
				ans[i]=ans[p[i]+1]+1;
			}
			sum+=ans[i];
		}

    	cout<<sum<<"\n";
	}
    return 0;
}

posted @ 2024-09-08 20:34  sad_lin  阅读(3)  评论(0编辑  收藏  举报