149D Coloring Brackets[區間dp]
阿新 • • 發佈:2019-02-02
題目要求是 給一個完整的括號匹配序列,問總共有多少種塗色方案:塗色滿足以下要求
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; }