Coloring Brackets
题意
给一个给定括号序列,给该括号上色,上色有三个要求
- 只有三种上色方案,不上色,上红色,上蓝色
- 每对括号必须只能给其中的一个上色
- 相邻的两个不能上同色,可以都不上色
求0-len-1这一区间内有多少种上色方案
#include <cstring>
#include <cstdio>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
const int maxn = 800;
char a[maxn];
ll dp[800][800][3][3];
int tmp[maxn];
int match[maxn];
/**
* 括号匹配位置
* @param len
*/
void getMatch(int len) {
int p = 0;
for (int i = 1; i <= len; i++) {
if (a[i] == '(') {
tmp[++p] = i;
} else {
match[i] = tmp[p];
match[tmp[p]] = i;
p--;
}
}
}
void dfs(int l, int r) {
if (l + 1 == r) {
dp[l][r][0][1] = 1;
dp[l][r][0][2] = 1;
dp[l][r][1][0] = 1;
dp[l][r][2][0] = 1;
return;
}
if (match[l] == r) {
dfs(l + 1, r - 1);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i != 1) {
dp[l][r][1][0] = (dp[l][r][1][0] + 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;
}
if (j != 1) {
dp[l][r][0][1] = (dp[l][r][0][1] + 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;
}
}
}
return;
} else {
int p = match[l];
dfs(l, p);
dfs(p + 1, r);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int q = 0; q < 3; q++) {
if (!((k == 1 && q == 1) || (k == 2 && q == 2))) {
dp[l][r][i][j] = (dp[l][r][i][j] + dp[l][p][i][k] * dp[p + 1][r][q][j] % mod) % mod;
}
}
}
}
}
}
}
int main() {
while (scanf("%s", a + 1) != EOF) {
int len = strlen(a + 1);
getMatch(len);
memset(dp, 0, sizeof(dp));
ll ans = 0;
dfs(1, len);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
ans = (ans + dp[1][len][i][j]) % mod;
}
}
printf("%lld\n", ans);
}
}