CodeForces 149D Coloring Brackets 区间DP

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

题意:

给一个给定括号序列,给该括号上色,上色有三个要求

1、只有三种上色方案,不上色,上红色,上蓝色

2、每对括号必须只能给其中的一个上色

3、相邻的两个不能上同色,可以都不上色

求0-len-1这一区间内有多少种上色方案

 

思路:dp[l][r][i][j]表示从l到r的长度且左右括号分别是i j的方案数

那么转移方程:

1: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;

2:s[l]和s[r]匹配时,dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])

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

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

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

3:不匹配时,dp[l][r][i][j]=(dp[l][r][i][j]+dp[l][p][i][k]*dp[p+1][r][q][j]);

且s[l]和s[p]匹配

 

  1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <iostream>
  6 #include <queue>
  7 #include <stack>
  8 #include <cmath>
  9 #include <set>
 10 #include <algorithm>
 11 #include <vector>
 12 // #include<malloc.h>
 13 using namespace std;
 14 #define clc(a,b) memset(a,b,sizeof(a))
 15 #define LL long long
 16 const int inf = 0x3f3f3f3f;
 17 const double eps = 1e-5;
 18 const double pi = acos(-1);
 19 const LL mod = 1e9+7; 
 20 const int N = 710;
 21 // inline int r(){
 22 //     int x=0,f=1;char ch=getchar();
 23 //     while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
 24 //     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 25 //     return x*f;
 26 // }
 27 LL dp[N][N][3][3];
 28 int match[N];
 29 char s[N];
 30 LL ans;
 31 int len;
 32 int tem[N];
 33 
 34 
 35 void init(){
 36     int p;
 37     p=0; 
 38     for(int i=0;i<len;i++){
 39         if(s[i]=='(') tem[p++]=i;
 40         else {
 41             match[i]=tem[p-1];
 42             match[tem[p-1]]=i;
 43             p--;
 44         }
 45     }
 46 }
 47 
 48 void dfs(int l,int r){
 49     if(l==r-1){
 50         dp[l][r][0][1]=1;
 51         dp[l][r][1][0]=1;
 52         dp[l][r][0][2]=1;
 53         dp[l][r][2][0]=1;
 54         return;
 55     }
 56     else if(match[l]==r){
 57         dfs(l+1,r-1);
 58         for(int i=0;i<3;i++){
 59             for(int j=0;j<3;j++){
 60                 if(j!=1) 
 61                 dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
 62                 if(i!=1)
 63                 dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
 64                 if(j!=2)
 65                 dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
 66                 if(i!=2)
 67                 dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;    
 68             }
 69         }
 70         return;  
 71     }
 72     else{
 73         int p=match[l];
 74         dfs(l,p);
 75         dfs(p+1,r);
 76         for(int i=0;i<3;i++){
 77             for(int j=0;j<3;j++){
 78                 for(int k=0;k<3;k++){
 79                     for(int q=0;q<3;q++){
 80                         if(!((k==1&&q==1)||(k==2&&q==2))){
 81                             dp[l][r][i][j]=(dp[l][r][i][j]+(dp[l][p][i][k]*dp[p+1][r][q][j])%mod)%mod;
 82                         }
 83                     }
 84                 }
 85             }
 86         }
 87         return;
 88     }
 89 }
 90 int main(){
 91     // freopen("in.txt","r",stdin);
 92     scanf("%s",s);
 93     len=strlen(s);
 94     // printf("%d\n",len);
 95     init();
 96     dfs(0,len-1);
 97     ans=0;
 98     for(int i=0;i<3;i++){
 99         for(int j=0;j<3;j++){
100             ans=(ans+dp[0][len-1][i][j])%mod;
101         }
102     }
103     printf("%I64d\n",ans);
104     return 0;
105 }

 

posted @ 2016-05-12 22:50  yyblues  阅读(200)  评论(0编辑  收藏  举报