题意:
假设,我们用一个包含 '(', ')'的括号字符串来区别每面鲤鱼旗的方向。一段括号序列被称为合法的,当且仅当满足两个条件:一、对于整个序列,左括号数量等于右括号;二、对于任意前缀,左括号的数目都不小于右括号的数目。岛娘想知道,对于一串括号字符串,有多少子串是合法的,你能帮助她么。
思路:
状态方式:dp[i]表示以i为结尾的串有多少串合法。
状态转移方程:pre[i]为i匹配的‘(',,,dp[i] = dp[pre[i]-1]+1;`````````````想到与把pre[i]前一个’)‘移动到i,再加上i本身
答案就是以所以位置为结尾的和;
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+7;
char str[maxn];
int dp[maxn];
int pos[maxn],pre[maxn];
int main()
{
scanf("%s",str+1);
int len = strlen(str+1);
dp[0] = 0;
int now = 0;
ll ans = 0;
for(int i = 1;i<=len;i++)
{
if(str[i]=='(')
pos[now++] = i;
else if(now!=0)
{
pre[i] = pos[--now];
}
else
pre[i] = 0;
if(pre[i])
{
dp[i] = dp[pre[i]-1]+1;
ans += dp[i];
}
}
printf("%lld\n",ans);
}