原題連結
題解
首先,假設當前 \(s(l,r)\) 括號序列為合法序列,則有如下幾種情況:
-
\(l+1==r\) ()
-
\(match[r]==l\) (...)
-
\(match[r]!=l\) (...)...(...)
code
#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7;
long long dp[705][705][3][3] = {0};
int match[705];
void dfs(int l, int r) {
if (l + 1 == r) {
dp[l][r][0][1] = dp[l][r][1][0] = dp[l][r][0][2] = dp[l][r][2][0] = 1;
return;
}
if (match[r] == l) {
dfs(l + 1, r - 1);
for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 2; j++) {
if (j != 1) dp[l][r][0][1] = (dp[l][r][0][1] + dp[l + 1][r - 1][i][j]) % MOD;
if (i != 1) dp[l][r][1][0] = (dp[l][r][1][0] + dp[l + 1][r - 1][i][j]) % MOD;
if (j != 2) dp[l][r][0][2] = (dp[l][r][0][2] + dp[l + 1][r - 1][i][j]) % MOD;
if (i != 2) dp[l][r][2][0] = (dp[l][r][2][0] + dp[l + 1][r - 1][i][j]) % MOD;
}
}
return;
}
int r1 = match[r] - 1, l1 = match[r];
dfs(l, r1);
dfs(l1, r);
for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 2; j++) {
for (int k = 0; k <= 2; k++) {
for (int m = 0; m <= 2; m++)
{
if(j==1&&k==1||j==2&&k==2) continue;
//if(i==j||i&&j) continue;if(k==m||k&&m) continue;這個要註釋掉是因為另外半部分的外圍括號可能不是配對的
dp[l][r][i][m] = (dp[l][r][i][m] + dp[l][r1][i][j] * dp[l1][r][k][m] % MOD) % MOD;
}
}
}
}
}
void solve() {
string s;
cin >> s;
int n = s.size();
stack<int> q;
for (int i = 0; i < n; i++) {
if (s[i] == ')') {
match[i] = q.top();
q.pop();
} else {
q.push(i);
}
}
dfs(0, n - 1);
long long ans = 0;
for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 2; j++) {
ans = (ans + dp[0][n - 1][i][j]) % MOD;
}
}
cout << ans << '\n';
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int TT = 1;
// cin >> TT;
while (TT--) solve();
return 0;
}