标签:ring else mask cto 相同 size tor include swap
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;
}
};
标签:ring else mask cto 相同 size tor include swap
原文地址:http://www.cnblogs.com/jianglangcaijin/p/6915067.html