考虑动态规划 F[i] 代表以第 i 个字符为结尾的平衡串个数, 预处理出每个与右括号匹配的左括号 j,如果存在的话, 那么 f[i]=f[j-1]+1; 复杂度也是 O(n)。
#include <stdio.h> #include <string.h> #include <math.h> #include <stack> #include <algorithm> using namespace std; typedef long long LL; const int N=1e6+5; const int INF=0x3f3f3f3f; int match[N],n; char s[N]; stack<int>st; LL dp[N][2]; int main(){ scanf("%s",s+1); n=strlen(s+1); LL ans=0; for(int i=1;i<=n;++i){ if(s[i]=='(')st.push(i); else { if(!st.empty()){ match[i]=st.top(); match[st.top()]=i; st.pop(); } } } for(int i=1;i<=n;++i){ dp[i][0]=dp[i-1][1]+dp[i-1][0]; if(match[i]>i||!match[i])continue; dp[i][1]=dp[match[i]-1][1]+1; } printf("%lld ",dp[n][0]+dp[n][1]); return 0; }