zoukankan      html  css  js  c++  java
  • Coloring Brackets

    题意:

    给一匹配的括号序列,要求每对括号恰有一个被染成蓝或红色,要求相邻的括号不同色,求方案数。

    解法:

    类比树的hash将括号序列转化为一棵树,树上子节点之间不得出现冲突,

    子节点和父节点不得出现冲突,问题转化为树形dp问题,$O(n)$解决。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 
      6 #define N 1000010
      7 #define LL long long
      8 #define P 1000000007LL
      9 
     10 using namespace std;
     11 
     12 /*
     13 1 -> 10
     14 2 -> 01
     15 3 -> 20
     16 4 -> 02
     17 */
     18 
     19 int totn;
     20 int next[N],q[N];
     21 LL f[N][5];
     22 LL h[N][3];
     23 char S[N];
     24 vector<int> G[N];
     25 
     26 int build(int l,int r)
     27 {
     28     int x=++totn;
     29     G[x].clear();
     30     l++;
     31     r--;
     32     while(l<r)
     33     {
     34         G[x].push_back(build(l,next[l]));
     35         l=next[l]+1;
     36     }
     37     return x;
     38 }
     39 
     40 void dp(int x)
     41 {
     42     int nl=G[x].size();
     43     if(!nl)
     44     {
     45         for(int i=1;i<5;i++)
     46             f[x][i]=1;
     47         return;
     48     }
     49     for(int i=0;i<nl;i++) dp(G[x][i]);
     50     for(int t=0;t<3;t++)
     51     {
     52         for(int i=0;i<3;i++) h[0][i]=0;
     53         h[0][t]=1;
     54         for(int i=1;i<=nl;i++)
     55         {
     56             int p=G[x][i-1];
     57             LL sum = (h[i-1][0]+h[i-1][1]+h[i-1][2])%P;
     58             h[i][1] = sum * f[p][2] % P;
     59             h[i][2] = sum * f[p][4] % P;
     60             
     61             h[i][0] = h[i-1][0]*f[p][1]%P + h[i-1][2]*f[p][1]%P;
     62             if(h[i][0]>=P) h[i][0]-=P;
     63             h[i][0] += h[i-1][0]*f[p][3]%P + h[i-1][1]*f[p][3]%P;
     64             if(h[i][0]>=P) h[i][0]-=P;
     65         }
     66         if(t==0)
     67         {
     68             f[x][0] = (h[nl][0] + h[nl][1] + h[nl][2]) % P;
     69             f[x][2] = (h[nl][0] + h[nl][2])%P;
     70             f[x][4] = (h[nl][0] + h[nl][1])%P;
     71         }
     72         else if(t==1) f[x][1] = (h[nl][0] + h[nl][1] + h[nl][2])%P;
     73         else f[x][3] = (h[nl][0] + h[nl][1] + h[nl][2])%P;
     74     }
     75 }
     76 
     77 int n;
     78 
     79 int main()
     80 {
     81     freopen("test.txt","r",stdin);
     82     while(~scanf("%s",S+1))
     83     {
     84         S[0]='(';
     85         n=strlen(S);
     86         S[n]=')';
     87         S[n+1]='';
     88         n++;
     89         int ed=0;
     90         totn=0;
     91         for(int i=0;i<n;i++)
     92         {
     93             if(S[i]=='(') q[++ed]=i;
     94             else
     95             {
     96                 next[q[ed]]=i;
     97                 ed--;
     98             }
     99         }
    100         build(0,n-1);
    101         dp(1);
    102         cout << f[1][0] << endl;
    103     }
    104     return 0;
    105 }
    106 /*
    107 (())
    108 (()())
    109 ()
    110 */
    View Code
  • 相关阅读:
    字符串操作练习:星座、凯撒密码、99乘法表、词频统计预处理
    条件、循环 、函数练习
    Python输入输出练习,运算练习,turtle初步练习
    steam游戏平台的数据分析
    浅谈微信三级分销系统的漏洞
    Efficient Inference in Fully Connected CRFs with Gaussian Edge Potentials阅读笔记
    Conditional Random Fields as Recurrent Neural Networks阅读笔记
    LeetCode824.Goat Latin
    LeetCode118.杨辉三角
    LeetCode500.键盘行
  • 原文地址:https://www.cnblogs.com/lawyer/p/6520306.html
Copyright © 2011-2022 走看看