CodeForces - 149D Coloring Brackets[区间dp]

原题链接       cf 149D Coloring Brackets

voj题目链接  cf 149D Coloring Brackets

 

 题目要求是 给一个完整的括号匹配序列,问总共有多少种涂色方案:涂色满足以下要求

1,每单个括号只能有三种情况,不涂色,涂红色和涂蓝色

2,每一对匹配的括号必须有且只有一个被涂色。

3,两个相邻的字符不能被涂相同 的颜色,


由于是对区间的涂色,可以考虑用区间dp,用 dp[i][j][k][t] 表示从i到j 区间被涂色后,i端涂的是k色,而j端涂的是t色。


渣渣代码,仅供参考:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 705
#define mod 1000000007
#define LL __int64
using namespace std;
LL dp[N][N][3][3];
char s[N];
int match[N];
void getmatch()
{
    int stack[N];
    int p=0;
    int len=strlen(s);
    for(int i=0; i<len; i++)
    {
        if(s[i]=='(')
            stack[p++]=i;
        else
        {
            match[i]=stack[p-1];
            match[stack[p-1]]=i;
            p--;
        }
    }
}

void dfs(int l,int r)
{
    if(l+1==r)
    {
        dp[l][r][0][1]=1;
        dp[l][r][1][0]=1;
        dp[l][r][0][2]=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(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;
    }
    else
    {
        int k=match[l];
        dfs(l,k);
        dfs(k+1,r);

        for(int h=0; h<3; h++)
            for(int t=0; t<3; t++)
                for(int i=0; i<3; i++)
                    for(int j=0; j<3; j++)
                        if(!((i==1&&j==1)||(i==2&&j==2)))
                            dp[l][r][h][t]=(dp[l][r][h][t]+(dp[l][k][h][i]*dp[k+1][r][j][t])%mod)%mod;

    }
}
int main()
{
     // freopen("in.txt","r",stdin);

    scanf("%s",s);
    getmatch();
    int len=strlen(s);

    memset(dp,0,sizeof(dp));
    dfs(0,len-1);
    LL ans=0;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            ans=(ans+dp[0][len-1][i][j])%mod;
    printf("%I64d\n",ans);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值