1. 程式人生 > >149D Coloring Brackets[區間dp]

149D Coloring Brackets[區間dp]

 題目要求是 給一個完整的括號匹配序列,問總共有多少種塗色方案:塗色滿足以下要求

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;
}