CF149D. Coloring Brackets[区间DP !]

不知道为什么居中了,先把代码放这

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=705,MOD=1e9+7;
char s[N];
long long n,f[N][N][5][5];
int st[N],top=0,m[N];
void match(){
    for(int i=1;i<=n;i++){
        if(s[i]==‘(‘) st[++top]=i;
        else{
            int tmp=st[top--];
            m[i]=tmp;
            m[tmp]=i;
        }
    }
}
void dp(int l,int r){//printf("dp %d %d\n",l,r);
    if(l>=r) return;
    if(l+1==r){
        f[l][r][0][1]=f[l][r][1][0]=f[l][r][0][2]=f[l][r][2][0]=1;
        return;
    }
    if(m[l]==r){
        dp(l+1,r-1);
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++){
                if(j!=1) f[l][r][0][1]=(f[l][r][0][1]+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!=1) f[l][r][1][0]=(f[l][r][1][0]+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{
        int p=m[l];
        dp(l,p);dp(p+1,r);
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    for(int t=0;t<3;t++){
                        if(k==1&&t==1) continue;
                        if(k==2&&t==2) continue;
                        //if(i!=0&&t!=0) continue;
                        f[l][r][i][j]=(f[l][r][i][j]+f[l][p][i][k]*f[p+1][r][t][j]%MOD)%MOD;
                    }
    }
    //printf("%d %d  %d %d %d %d\n",l,r,f[l][r][0][1],f[l][r][0][2],f[l][r][1][0],f[l][r][2][0]);
}
//void dp(int l,int r,int a,int b){
//    int &ans=f[l][r][a][b];
//    if(ans!=-1) return ans;
//
//}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    match();
    dp(1,n);
    long long ans=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            ans=(ans+f[1][n][i][j])%MOD;

    printf("%d",ans);
}

D. Coloring Brackets

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Once Petya read a problem about a bracket sequence. He gave it much thought but didn‘t find a solution. Today you will face it.

You are given string s. It represents a correct bracket sequence. A correct bracket sequence is the sequence of opening ("(") and closing (")") brackets, such that it is possible to obtain a correct mathematical expression from it, inserting numbers and operators between the brackets. For example, such sequences as "(())()" and "()" are correct bracket sequences and such sequences as ")()" and "(()" are not.

In a correct bracket sequence each bracket corresponds to the matching bracket (an opening bracket corresponds to the matching closing bracket and vice versa). For example, in a bracket sequence shown of the figure below, the third bracket corresponds to the matching sixth one and the fifth bracket corresponds to the fourth one.

You are allowed to color some brackets in the bracket sequence so as all three conditions are fulfilled:

  • Each bracket is either not colored any color, or is colored red, or is colored blue.
  • For any pair of matching brackets exactly one of them is colored. In other words, for any bracket the following is true: either it or the matching bracket that corresponds to it is colored.
  • No two neighboring colored brackets have the same color.

Find the number of different ways to color the bracket sequence. The ways should meet the above-given conditions. Two ways of coloring are considered different if they differ in the color of at least one bracket. As the result can be quite large, print it modulo1000000007 (109 + 7).

Input

The first line contains the single string s (2 ≤ |s| ≤ 700) which represents a correct bracket sequence.

Output

Print the only number — the number of ways to color the bracket sequence that meet the above given conditions modulo 1000000007(109 + 7).

Examples

input

(())

output

12

input

(()())

output

40

input

()

output

4

Note

Let‘s consider the first sample test. The bracket sequence from the sample can be colored, for example, as is shown on two figures below.

The two ways of coloring shown below are incorrect.


题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数


区间DPf[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数听说用记忆化搜索比较快,可以像树形DP那样写记忆化搜索用循环简化枚举注意细节 见代码

时间: 2024-10-08 10:43:56

CF149D. Coloring Brackets[区间DP !]的相关文章

codeforces 149D - Coloring Brackets (区间dp)

题目大意: 给出一组合法的括号. 括号要么不涂颜色,要么就涂上红色或者绿色. 匹配的括号只能有一个有颜色. 两个相邻的括号不能有相同的颜色. 思路分析: 因为是一个合法的括号序列. 所以每个括号与之匹配的位置是一定的. 那么就可以将这个序列分成两个区间. (L - match[L] )  (match[L]+1, R) 用递归先处理小区间,再转移大区间. 因为条件的限制,所以记录区间的同时,还要记录区间端点的颜色. 然后就是一个递归的过程. #include <cstdio> #include

codeferces 149D Coloring Brackets 区间dp

http://codeforces.com/problemset/problem/149/D 题目大致意思是给你一串字符串,只有小括号,并且已经符合括号匹配规则,现在要给这些括号涂色,给出一些涂色规则,求涂色的方案数. 1: 括号要么不被涂色,要么被涂成蓝色,要么被涂成红色. 2:两个相互匹配的括号有且仅有一个被涂色. 3:相邻两个括号不可以有相同颜色. 这里当然也是想到对区 [l, r] 间进行dp,但是这里对颜色有依赖关系,所以还需要记入 l 和 r 颜色的状态,一开始打算只用一维记录两个点

POJ 2955 Brackets (区间DP)

题意:给定一个序列,问你最多有多少个合法的括号. 析:区间DP,dp[i][j] 表示在 第 i 到 第 j 区间内最多有多少个合法的括号. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <ios

POJ 2955 Brackets (区间dp 括号匹配)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3951   Accepted: 2078 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

POJ 2955:Brackets 区间DP基础题

Brackets 题目链接: http://poj.org/problem?id=2955 题意: 给出一个只由'('.')'.'['.']'构成的字符串,字符间可以匹配,左边的 '(' 可以与右边的 ')' 匹配,左边的 '[' 可以与右边的 ']' 匹配 两种匹配不能交叉,可以包含,如 [(])只算2个匹配而[()]算四个匹配,求最大匹配数. 题解: 设dp[i][j]为区间 i 到 j (设len为区间长度,j=i+len)内可以得到的最大匹配数,则有两种情况: ① j 不与区间[i,j]

poj2955 Brackets (区间dp)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3571   Accepted: 1847 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

poj 2955 Brackets(区间DP求最长匹配子串)

思路:假设要求区间[i,j]的最长匹配字串,它必然可以从[i,j-1]转移而来,有可能是s[j]与s[i]发生"关系"(匹配或不匹配),一直到s[j-1],若不发生"关系",即s[j]跟自己发生"关系",用for循环枚举所有的可能,取最大值. 代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char

POJ2955:Brackets(区间DP)

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define pf(x) printf("%d\n", x) 6 #define CL(x, y) memset(x, y, sizeof(x)) 7 #define max(a, b) (a > b ? a : b) 8 using namespace s

POJ 2955 Brackets 区间DP 最大括号匹配

http://blog.csdn.net/libin56842/article/details/9673239 http://www.cnblogs.com/ACMan/archive/2012/08/09/2630497.html http://blog.csdn.net/chaiyuan414/article/details/5448699 #include <iostream> #include <string> #include <cstring> #inclu