一开始以为匹配括号有多个。。。最后发现测试数据都不对。。。
题意:给定一个保证括号匹配的序列,现需要给它染色。
要求一、相邻的括号颜色不同 二、匹配的括号必须只有一个染色 三、每个括号有三种选择无色、蓝色、红色。问有多少种染色方案。
思路:dp[i][j][c1][c2]表示 i染c1且j染c2时 区间[i, j]的染色方案。预处理括号i的匹配括号fp[i]。
考虑区间[i, j](c1, c2)
有两种情况:
一、i j是正好匹配的,判断是否合法后,统计符合条件的所有情况即可。
二、i j不匹配,那么将区间[i, j]分为[i, fp[i]]*[fp[i]+1, j],枚举合法的状态统计即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (100000+10)
#define MAXM (200000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#define first fi
#define second se
using namespace std;
char s[800];
LL dp[800][800][3][3];
int fp[MAXN];
bool judge(int c1, int c2){
return c1 == 0 || c2 == 0 || c1 != c2;
}
LL DFS(int i, int j, int c1, int c2)
{
if(dp[i][j][c1][c2] != -1) return dp[i][j][c1][c2];
if(i + 1 > j) return dp[i][j][c1][c2] = 0;
if(i == j) return dp[i][j][c1][c2] = 1LL;
LL ans = 0; int k = fp[i];
if(k == j)
{
if((c1 == 0 && c2) || (c1 && c2 == 0))
{
if(i + 1 == j) return dp[i][j][c1][c2] = 1LL;
for(int a = 0; a <= 2; a++)
for(int b = 0; b <= 2; b++)
if(judge(c1, a) && judge(b, c2))
ans = (ans + DFS(i+1, j-1, a, b)) % MOD;
}
}
else if(k < j)
{
for(int a = 0; a <= 2; a++)
for(int b = 0; b <= 2; b++)
if(judge(a, b))
ans = (ans + DFS(i, k, c1, a) * DFS(k+1, j, b, c2)) % MOD;
}
return dp[i][j][c1][c2] = ans;
}
int main()
{
Rs(s); int len = strlen(s);
stack<int> S;
for(int i = 0; i < len; i++)
{
if(s[i] == '(')
S.push(i);
else
{
fp[S.top()] = i;
S.pop();
}
}
CLR(dp, -1); LL ans = 0;
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
ans = (ans + DFS(0, len-1, i, j)) % MOD;
Pl(ans);
return 0;
}