您的位置:首页 > 其它

Codeforces 149D - Coloring Brackets(区间DP)

2015-06-06 16:41 375 查看
题目:

http://codeforces.com/problemset/problem/149/D

题意:

对括号字符串进行染色:

1.每个括号可以染色或不染色。

2.每对括号有且仅有一个染色。

3.相邻的括号颜色不同或都无色。

思路:

dp[l][r][i][j]: 区间(l,r)左右颜色分别为i,j的方案数。

0:无色,1:红色,2:蓝色。

1. l +1 = r : 表示只剩下一个括号的区间。

2. mch[l] = r: 括号匹配, dfs(l+1,r-1)

dp[l][r][0][1] = (dp[l][r][0][1] + dp[l+1][r-1][i][j]) % mod;

 dp[l][r][0][2] = (dp[l][r][0][2] + dp[l+1][r-1][i][j]) % mod;

dp[l][r][1][0] = (dp[l][r][1][0] + dp[l+1][r-1][i][j]) % mod;

dp[l][r][2][0] = (dp[l][r][2][0] + dp[l+1][r-1][i][j]) % mod;

3. 不匹配,

dp[l][r][i][q] = (dp[l][r][i][q] + (dp[l][p][i][j]*dp[p+1][r][k][q])%mod)%mod;

AC.

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int mod = 1e9+7;
char s[705];
long long dp[705][705][3][3];
int t[705], mch[705];

void getmatch(int n)
{
int k = 0;
for(int i = 0; i < n; ++i) {
if(s[i] == '(') t[k++] = i;
else {
mch[i] = t[k-1];
mch[t[k-1]] = i;
k--;
}
}
}

void dfs(int l, int r)
{
if(l + 1 == r) {
dp[l][r][0][2] = 1;
dp[l][r][2][0] = 1;
dp[l][r][0][1] = 1;
dp[l][r][1][0] = 1;
return;
}
if(mch[l] == r) {
dfs(l+1, r-1);
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
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;
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;
}
}
return;
}
else {
int p = mch[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(!((j==1&&k==1) || (j==2&&k==2))) {
dp[l][r][i][q] = (dp[l][r][i][q] + (dp[l][p][i][j]*dp[p+1][r][k][q])%mod)%mod;
}
}
}
}
}

}
}
int main()
{
// freopen("in", "r", stdin);
while(~scanf("%s", s)) {
int n = strlen(s);
memset(t, 0, sizeof(t));
memset(mch, 0, sizeof(mch));
memset(dp, 0, sizeof(dp));
getmatch(n);
dfs(0, n-1);
long long ans = 0;
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
ans = (ans + dp[0][n-1][i][j])%mod;
}
}
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codeforces