CodeForces 149D Coloring Brackets(JAVA版)

来源:互联网 发布:js sleep函数 编辑:程序博客网 时间:2024/05/18 03:25

CodeForces 149D Coloring Brackets

题目大意:给一串字符串,只包含“(”、“)”,相互之间已经匹配好了,想要给字符串着色,问有多少种着色方案。限制条件如下:1.每一个括号只能是无色、红色、蓝色三者之一;2.对于任意一对括号,只能有一个是着色的;3.任意相邻的两个括号,颜色不能相同。因为数据很大,所以答案对1000000007取模。

思路如下:因为给定的是一个已经匹配好的括号序列,所以每个括号的匹配对象是固定的,所以可以找出他们相互之间的匹配关系。开一个四维数组dp[n][n][3][3],可以假设比如0是无色,1是红,2是蓝色。dp[i][j][m][n]表示字符串的第 i 位到第 j 位,i 括号着了m色,j 括号着了n色,这样的情况一共有多少组合方案。用match[n]数组记录匹配对象,如match[i]==j表示 i 与 j 匹配,则可得出如下状态转移方程:(下面省略全部的取模运算)

当i、j相邻时:dp[i][j][1][0]=1;dp[i][j][0][1]=1;dp[i][j][2][0]=1;dp[i][j][0][2]=1。

当i、j匹配时:dp[i][j][1][0]+=dp[i+1][j-1][m][n](m!=1);dp[i][j][0][1]+=dp[i+1][j-1][m][n](n!=1);dp[i][j][2][0]+=dp[i+1][j-1][m][n](m!=2);dp[i][j][0][2]+=dp[i+1][j-1][m][n](n!=2)。

当i、j不匹配时:dp[i][j][m][n]+=dp[i][match[i]][m][x]*dp[match[i]+1][j][y][n](当m=n=1 || m=n=2不成立时)。

最后求结果时只需sum+=dp[1][n][m][n](0<=m,n<3)全部加起来即可(再取模)。

ps:取模的地方一直想改,感觉或许可以简化,但是每次一改就wa,只好直接在每个计算dp的地方取一次模~

AC代码:

import java.util.Scanner;public class 动态规划2H_coloringBrackets{static Scanner scan=new Scanner(System.in);static int mod=1000000007;public static void getMatch(int n, char[] a, int[] b, int[] temp)//配对{int pop=1;for(int i=1;i<n+1;i++)if(a[i]=='(')temp[pop++]=i;else{b[i]=temp[pop-1];b[temp[pop-1]]=i;pop--;}}public static void count(int l, int r, long[][][][] dp, int[] match)//递归,记忆化搜索{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){count(l+1, r-1, dp, match);for(int i=0;i<3;i++)for(int j=0;j<3;j++){if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+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;if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;}return;}else{count(l, match[l], dp, match);count(match[l]+1, r, dp, match);for(int i=0;i<3;i++)                for(int j=0;j<3;j++)                  for(int m=0;m<3;m++)                      for(int n=0;n<3;n++)                          if(!((m==1 && n==1) || (m==2 && n==2)))                        dp[l][r][i][j]=(dp[l][r][i][j]+dp[l][match[l]][i][m]*dp[match[l]+1][r][n][j])%mod;   }}public static void main(String[] args){String str=scan.next();int n=str.length();char a[]=new char[n+1];for(int i=1;i<n+1;i++)a[i]=str.charAt(i-1);int match[]=new int[n+1];int temp[]=new int[n+1];getMatch(n, a, match, temp);long dp[][][][]=new long[n+1][n+1][3][3];long sum=0;count(1, n, dp, match);for(int i=0;i<3;i++)for(int j=0;j<3;j++)sum+=dp[1][n][i][j];System.out.println(sum%mod);}}

0 0