您的位置:首页 > 其它

Codeforce 149D(区间dp+括号匹配)

2016-05-07 15:22 281 查看
链接:点击打开链接

题意:给一个给定括号序列,给该括号序列上色,上色有三个要求1.每个括号只有三种情况,不上色,上红色,上蓝色,2.每对括号必须只能给其中的一个上色3.相邻的两个不能上同色,可以都不上色,求所有的上色种数

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const long long MOD=1000000007;
char s[705];
long long dp[705][705][3][3],a[705],b[705];
int main(){
long long i,j,k,l,p,x,y,xx,yy,ans,len;
while(scanf("%s",s+1)!=EOF){
p=1;
len=strlen(s+1);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(dp,0,sizeof(dp));
for(i=1;i<=len;i++){
if(s[i]=='(')
a[p++]=i;
else{
b[a[p-1]]=i;
b[i]=a[p-1];
p--;
}
}                                       //模拟栈进行括号匹配
for(i=1;i<len;i++)
if(b[i]==i+1){
dp[i][i+1][0][1]=dp[i][i+1][1][0]=1;
dp[i][i+1][0][2]=dp[i][i+1][2][0]=1;
}
for(l=2;l<=len;l++){
for(i=1;i<=len-l+1;i++){
j=i+l-1;
if(b[i]==j){
dp[i][j][0][1]+=(dp[i+1][j-1][0][0]+dp[i+1][j-1][1][0]+dp[i+1][j-1][2][0]+dp[i+1][j-1][0][2]+dp[i+1][j-1][1][2]+dp[i+1][j-1][2][2])%MOD;
dp[i][j][0][2]+=(dp[i+1][j-1][0][0]+dp[i+1][j-1][0][1]+dp[i+1][j-1][1][0]+dp[i+1][j-1][1][1]+dp[i+1][j-1][2][0]+dp[i+1][j-1][2][1])%MOD;
dp[i][j][1][0]+=(dp[i+1][j-1][0][0]+dp[i+1][j-1][0][1]+dp[i+1][j-1][2][0]+dp[i+1][j-1][0][2]+dp[i+1][j-1][2][1]+dp[i+1][j-1][2][2])%MOD;
dp[i][j][2][0]+=(dp[i+1][j-1][0][0]+dp[i+1][j-1][0][1]+dp[i+1][j-1][1][0]+dp[i+1][j-1][1][1]+dp[i+1][j-1][0][2]+dp[i+1][j-1][1][2])%MOD;
}                               //匹配的括号只能有一个染色并且颜色不能相同
else if(b[i]<j){
for(x=0;x<=2;x++)
for(y=0;y<=2;y++)
for(xx=0;xx<=2;xx++)
for(yy=0;yy<=2;yy++)
if(xx==0||yy==0||xx!=yy){
dp[i][j][x][y]+=(dp[i][b[i]][x][xx]*dp[b[i]+1][j][yy][y])%MOD;
dp[i][j][x][y]%=MOD;
}                           //处理相邻两个括号不能是相同颜色的情况
}
}
}
ans=0;
for(i=0;i<=2;i++)
for(j=0;j<=2;j++)
ans=(ans+dp[1][len][i][j])%MOD;
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: