CodeForces

来源:互联网 发布:带着淘宝去古代txt 编辑:程序博客网 时间:2024/06/05 03:48

题意:给你一个完整的括号匹配让你涂色,涂色的条件是

一个括号必须涂一边,而且只能涂一边。相邻的颜色不能相同而且只能涂蓝色和红色,然后求涂色方案数

题解:用思维然后dp[l][r][lc][rc]表示我此时涂的是第l到第r个括号边,lc表示之前左边涂的颜色,rc表示之前右边涂的颜色,0表示没涂,1表示涂蓝,2表示涂红色

然后判断l和r是在同一个括号,两个相邻的括号,两个括号不相邻的这些情况怎么转移一下即可


#include<iostream>#include<cstring>#include<cstdio>#include<stack>#include<algorithm>using namespace std;typedef long long int ll;const int mod = 1e9+7;const int mx = 705;ll dp[mx][mx][3][3];char s[mx];int p[mx];stack<int>st;ll dfs(int l,int r,int lc,int rc){    if(l>=r)    return 1;    if(dp[l][r][lc][rc]!=-1)    return dp[l][r][lc][rc];    int x = p[l];    int y = p[r];    dp[l][r][lc][rc] = 0;    if(x==r){        for(int i = 1; i <= 2; i++)            if(i!=rc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,0,i))%mod;        for(int i = 1; i <= 2; i++)            if(i!=lc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,i,0))%mod;    }    else if(x+1==y){        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(i!=lc&&j!=rc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,0,j))%mod;        for(int i = 1;  i<= 2; i++)            for(int j = 1;  j <= 2; j++)                if(i!=j)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,j,0))%mod;        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(i!=lc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,j,0))%mod;        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(j!=rc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,0,j))%mod;    }    else{        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(i!=lc&&j!=rc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,0)%mod*dfs(y+1,r-1,0,j))%mod;        for(int i = 1;  i<= 2; i++)            for(int j = 1;  j <= 2; j++)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,j)%mod*dfs(y+1,r-1,j,0))%mod;        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(i!=lc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,j)%mod*dfs(y+1,r-1,j,0))%mod;        for(int i = 1; i <= 2; i++)            for(int j = 1; j <= 2; j++)                if(j!=rc)                dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,0)%mod*dfs(y+1,r-1,0,j))%mod;    } //   cout<<dp[l][r][lc][rc]<<endl;;    return dp[l][r][lc][rc];}int main(){    memset(dp,-1,sizeof(dp));    int n;    scanf("%s",s+1);    n = strlen(s+1);    for(int i = 1; i <= n; i++)        if(s[i]=='(')            st.push(i);        else{            p[st.top()] = i;            p[i] = st.top();            st.pop();        }    ll ans = dfs(1,n,0,0);    printf("%I64d\n",ans);    return 0;}


原创粉丝点击