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 }