您的位置:首页 > 编程语言 > Java开发

CodeForces 149D Coloring Brackets(JAVA版)

2014-02-22 17:48 423 查看
CodeForces 149D Coloring Brackets

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

思路如下:因为给定的是一个已经匹配好的括号序列,所以每个括号的匹配对象是固定的,所以可以找出他们相互之间的匹配关系。开一个四维数组dp

[3][3],可以假设比如0是无色,1是红,2是蓝色。dp[i][j][m]
表示字符串的第 i 位到第 j 位,i 括号着了m色,j 括号着了n色,这样的情况一共有多少组合方案。用match
数组记录匹配对象,如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]
(m!=1);dp[i][j][0][1]+=dp[i+1][j-1][m]
(n!=1);dp[i][j][2][0]+=dp[i+1][j-1][m]
(m!=2);dp[i][j][0][2]+=dp[i+1][j-1][m]
(n!=2)。

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

最后求结果时只需sum+=dp[1]
[m]
(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]
[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]
[i][j];

System.out.println(sum%mod);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: