• CodeForces 149D Coloring Brackets(区间dp)


    题意:

    给一个给定括号序列,给该括号上色,上色有三个要求

    1、只有三种上色方案,不上色,上红色,上蓝色

    2、每对括号必须只能给其中的一个上色

    3、相邻的两个不能上同色,可以都不上色

    求0-len-1这一区间内有多少种上色方案

    我按最基本的区间dp思路果断跑了810ms,看了别人30ms的代码。。

    就是要找0到n-1区间的方案数,当用到l到r区间的方案数时递归找l到r区间方案数

    这样就省去记录所有的状态了

    因为如果i与j不匹配的时候,只需要找到i到u和u+1到j的方案数就可以了(u为与i匹配的括号)

    附上我的渣渣代码~

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <cstdio>
    using namespace std;
    const int mod=1e9+7;
    char s[710];
    int n,mapp[710];
    long long dp[710][710][3][3];
    void getmap()
    {
        memset(mapp,0,sizeof(mapp));
        stack<int>q;
        while(!q.empty()) q.pop();
        for(int i=0; i<n; i++)
        {
            if(s[i]=='(') q.push(i);
            else
            {
                if(q.empty()) continue;
                int p=q.top();
                q.pop();
                mapp[p]=i;
                mapp[i]=p;
            }
        }
    }
    void solve()
    {
        while(~scanf("%s",s))
        {
            n=strlen(s);
            getmap();
            memset(dp,0,sizeof(dp));
            for(int i=0; i<n-1; i++)
            {
                dp[i][i+1][0][1]=dp[i][i+1][0][2]=dp[i][i+1][1][0]=dp[i][i+1][2][0]=1;
                if(mapp[i]!=i+1)
                    dp[i][i+1][0][0]=dp[i][i+1][1][2]=dp[i][i+1][2][1]=1;
            }
            for(int l=2; l<n; l++)
            {
                for(int i=0; i+l<n; i++)
                {
                    int j=i+l;
                    if(mapp[i]==j)
                    {
                        for(int p=0; p<=2; p++)
                        {
                            for(int q=0; q<=2; q++)
                            {
                                if(q!=1)
                                    dp[i][j][0][1]=(dp[i][j][0][1]+dp[i+1][j-1][p][q])%mod;
                                if(p!=1)
                                    dp[i][j][1][0]=(dp[i][j][1][0]+dp[i+1][j-1][p][q])%mod;
                                if(q!=2)
                                    dp[i][j][0][2]=(dp[i][j][0][2]+dp[i+1][j-1][p][q])%mod;
                                if(p!=2)
                                    dp[i][j][2][0]=(dp[i][j][2][0]+dp[i+1][j-1][p][q])%mod;
                            }
                        }
                    }
                    else
                    {
                        int u=mapp[i];
                        for(int p=0; p<=2; p++)
                            for(int q=0; q<=2; q++)
                                for(int x=0; x<=2; x++)
                                    for(int y=0; y<=2; y++)
                                        if(!((x==1&&y==1)||(x==2&&y==2)))
                                            dp[i][j][p][q]=(dp[i][j][p][q]+(dp[i][u][p][x]*dp[u+1][j][y][q])%mod)%mod;
                    }
                }
            }
            long long ans=0;
            for(int i=0; i<=2; i++)
                for(int j=0; j<=2; j++)
                    ans=(ans+dp[0][n-1][i][j])%mod;
            printf("%lld
    ",ans);
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        solve();
        return 0;
    }
  • 相关阅读:
    Numpy(0)
    C++(成员函数做友元)
    C++(类做友元)
    CUDA---Arrayfire---添加cuda kernel
    CUDA--Arrayfire--类型转换
    C++(友元)
    C++(const修饰成员函数)
    C++(空指针访问成员函数)
    第9章 整合前端
    第8章 离不开的数据库
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5296565.html
Copyright © 2020-2023  润新知