首页 > 代码库 > topcoder srm 686 div1 -3

topcoder srm 686 div1 -3

1、给出只包含‘(‘,‘)‘,‘[‘,‘]‘的字符串$s$,删除一些字符,使得剩下的是合法的括号。有多少种删除方法? $|s|\leq 40$

思路:左括号和右括号较少的一种不会大于20。假设左括号少。设$f[i][mask][k]$表示处理了前$i$个字符,其中留下的字符以$k$开头($k=0$表示‘(‘,$k=1$表示‘[‘),且所有留下的字符状态为$mask$,($mask$的最高位为1,其他位为0表示另一种括号,否则表示跟最高位相同的符号)。

#include <stdio.h>#include <string.h>#include <string>#include <iostream>#include <vector>#include <set>#include <map>#include <queue>#include <algorithm>#include <stack>using namespace std;long long f[2][1<<20][2];class BracketSequenceDiv1{public:	long long count(string s)	{	    const int n=(int)s.size();	    int L=0,R=0;	    for(int i=0;i<n;++i)        {            if(s[i]==‘(‘||s[i]==‘[‘) ++L;            else ++R;        }        if(L>R)        {            reverse(s.begin(),s.end());            for(int i=0;i<n;++i)            {                if(s[i]==‘(‘) s[i]=‘)‘;                else if(s[i]==‘)‘) s[i]=‘(‘;                else if(s[i]==‘[‘) s[i]=‘]‘;                else s[i]=‘[‘;            }            swap(L,R);        }        int pre=0,cur=1;        memset(f[pre],0,sizeof(f[pre]));        f[0][0][0]=1;        for(int i=1;i<=n;++i)        {            char c=s[i-1];            memset(f[cur],0,sizeof(f[cur]));            for(int j=0;j<(1<<L);++j) for(int k=0;k<2;++k) if(f[pre][j][k])            {                long long p=f[pre][j][k];                f[cur][j][k]+=p;                if(c==‘(‘)                {                    if(j==0)      f[cur][1][0]+=p;                    else f[cur][j<<1|(!k)][k]+=p;                }                else if(c==‘[‘)                {                    if(j==0) f[cur][1][1]+=p;                    else f[cur][j<<1|k][k]+=p;                }                else if(c==‘)‘)                {                    if(j!=0&&(k^(j&1))) f[cur][j>>1][k]+=p;                }                else                {                    if(j!=0&&(0==(k^(j&1)))) f[cur][j>>1][k]+=p;                }            }            pre^=1;            cur^=1;        }        return f[pre][0][0]+f[pre][0][1]-1;	}};

  

topcoder srm 686 div1 -3