牛客网NOIP赛前集训营-普及组(第一场)C 括号
思路:
dp
状态:dp[i][j]表示到i位置为止未匹配的 '(' 个数为j的方案数
状态转移:
如果s[i] == '('
dp[i][j] = dp[i-1][j] + dp[i-1][j-1]
如果s[i] == ')'
dp[i][j] = dp[i-1][j] + dp[i-1][j+1]
优化:用滚动数组优化掉i这一维度
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long #define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e4 + 10; const int MOD = 1e9 + 7; char s[N]; int dp[2][N]; int main() { int n; scanf("%d", &n); scanf("%s", s+1); int now = 0; dp[now][0] = 1; for (int i = 1; i <= n; i++) { now ^= 1; if(s[i] == '(') { for(int i = 0; i < n; i++) { dp[now][i+1] = (dp[now^1][i+1] + dp[now^1][i]) % MOD; } dp[now][0] = dp[now^1][0]; } else { for (int i = 1; i <= n; i++) { dp[now][i-1] = (dp[now^1][i-1] + dp[now^1][i]) % MOD; } dp[now][n] = dp[now^1][n]; } } printf("%d\n", (dp[now][0] + MOD - 1) % MOD); return 0; }