• CodeForces 149D Coloring Brackets


    区间DP。dp[i][j][h][k]表示[i,j]这段区间染色,左端点为颜色h,右端点为颜色k的方案数。

    递推式很容易写出来。注意中间过程爆int。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    const int MOD = 1e9 + 7;
    const int maxn = 1000;
    char s[maxn];
    long long dp[maxn][maxn][3][3];
    int len;
    int link[maxn];
    int Stack[maxn], top;
    
    void init()
    {
        len = strlen(s);
        for (int i = len - 1; i >= 0; i--) s[i + 1] = s[i];
        memset(dp, 0, sizeof dp);
    }
    
    void work()
    {
        for (int i = 1; i <= len; i++)
        {
            if (i % 2 != 0) continue;
            for (int j = 1; j <= len; j++)
            {
                int st = j, en = st + i - 1;
                if (en > len) break;
                if (i == 2)
                {
                    if (s[st] == '('&&s[en] == ')')
                    {
                        dp[st][en][1][0] = dp[st][en][2][0] = 1;
                        dp[st][en][0][1] = dp[st][en][0][2] = 1;
                    }
                    continue;
                }
    
                if (link[st]==en)
                {
                    for (int k = 0; k<3; k++)
                        for (int h = 0; h<3; h++)
                            if (k != 1) dp[st][en][1][0] = (dp[st][en][1][0] + dp[st + 1][en - 1][k][h]) % MOD;
    
                    for (int k = 0; k<3; k++)
                        for (int h = 0; h<3; h++)
                            if (k != 2) dp[st][en][2][0] = (dp[st][en][2][0] + dp[st + 1][en - 1][k][h]) % MOD;
    
                    for (int k = 0; k<3; k++)
                        for (int h = 0; h<3; h++)
                            if (h != 1) dp[st][en][0][1] = (dp[st][en][0][1] + dp[st + 1][en - 1][k][h]) % MOD;
    
                    for (int k = 0; k<3; k++)
                        for (int h = 0; h<3; h++)
                            if (h != 2) dp[st][en][0][2] = (dp[st][en][0][2] + dp[st + 1][en - 1][k][h]) % MOD;
                    continue;
                }
    
                int p = link[st];
                for (int k = 0; k<3; k++)
                    for (int h = 0; h<3; h++)
                        for (int kk = 0; kk<3; kk++)
                            for (int hh = 0; hh<3; hh++)
                                if (!((kk == 1 && hh == 1) || (kk == 2 && hh == 2)))
                                    dp[st][en][k][h] = (
                                    dp[st][en][k][h] +
                                    (dp[st][p][k][kk] * dp[p + 1][en][hh][h]) % MOD
                                    ) % MOD;
            }
        }
        long long ans = 0;
        for (int k = 0; k<3; k++)
            for (int h = 0; h<3; h++)
                ans = (ans + dp[1][len][k][h]) % MOD;
        printf("%lld
    ", ans);
    }
    
    void f()
    {
        memset(link, -1, sizeof link);
        top = -1;
        for (int i = 1; i <= len; i++)
        {
            if (top == -1) Stack[++top] = i;
            else
            {
                if (s[i] == ')') { link[Stack[top]] = i; top--; }
                else Stack[++top] = i;
            }
        }
    }
    
    int main()
    {
        while (~scanf("%s", s))
        {
            init();
            f();
            work();
        }
        return 0;
    }
  • 相关阅读:
    Ruby 操作 Mysql (2)
    有关SQL模糊查询【转载】
    vim命令行大全【转载】
    Ruby连接MySQL
    c# 操作mysql
    sublime 3 快捷键大全
    VS2010快捷键大全
    [使用Xpath对XML进行模糊查询]
    vim永久显示行号
    Ubuntu16.04LTS安装flash player
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5225376.html
Copyright © 2020-2023  润新知