【CF 149D】Coloring Brackets
阿新 • • 發佈:2018-12-11
解析:
這道題主要難在情況有點多,稍微思路不清晰就會GG。
題目大意:
給一個給定括號序列,給該括號上色,上色有三個要求
1、只有三種上色方案,不上色,上紅色,上藍色
2、每對括號必須只能給其中的一個上色
3、相鄰的兩個不能上同色,可以都不上色
求這一區間內有多少種上色方案,很明顯的區間DP
]表示區間兩端顏色分別是i,j的方案數
0代表不上色,1代表上紅色,2代表上藍色
對於區間,有3種情況:
1、如果 說明就只有一對,那麼
2、如果與是配對的
遞迴
狀態轉移
3、如果與不配對
程式碼:
#include <bits/stdc++.h> using namespace std; const int mod=1e9+7; const int Max=705; int n,m,tot,pos,p[Max]; long long ans; long long f[Max][Max][3][3]; char ch[Max]; inline void pre() { n=strlen(ch+1); for(int i=1;i<=n-1;i++) { if(ch[i]==')') continue; int sum=0; for(int j=i+1;j<=n;j++) { if(ch[j]=='(') sum++; else sum--; if(sum==-1) {p[i]=j,p[j]=i;break;} } } } inline void solve(int l,int r) { if(l+1==r) { f[l][r][0][1]=1; f[l][r][1][0]=1; f[l][r][0][2]=1; f[l][r][2][0]=1; return; } if(p[l]==r) { solve(l+1,r-1); for(int i=0;i<=2;i++) for(int j=0;j<=2;j++) { if(j!=1) f[l][r][0][1]=(f[l][r][0][1]+f[l+1][r-1][i][j])%mod; if(i!=1) f[l][r][1][0]=(f[l][r][1][0]+f[l+1][r-1][i][j])%mod; if(j!=2) f[l][r][0][2]=(f[l][r][0][2]+f[l+1][r-1][i][j])%mod; if(i!=2) f[l][r][2][0]=(f[l][r][2][0]+f[l+1][r-1][i][j])%mod; } } else { solve(l,p[l]),solve(p[l]+1,r); for(int i=0;i<=2;i++) for(int j=0;j<=2;j++) for(int k=0;k<=2;k++) for(int q=0;q<=2;q++) { if(k==q&&k&&q) continue; f[l][r][i][j]=(f[l][r][i][j]+f[l][p[l]][i][k]*f[p[l]+1][r][q][j]%mod)%mod; } } } int main() { scanf("%s",ch+1); pre(); solve(1,n); for(int i=0;i<=2;i++) for(int j=0;j<=2;j++) ans=(ans+f[1][n][i][j])%mod; cout<<ans; return 0; }