玄学字符串dp...

题意:给定一个括号序列,求长度为2n的合法的括号序列的个数(要求每个被统计的合法序列中均至少有一个子串为给定的括号序列)

题解:

这题没有想的那么复杂,就是暴力的一个dp

首先我们设状态f[i][j][k][0/1]表示当前放到了第i个括号,前i个括号中左右括号个数差为j,已经放好的括号中长为k的部分能与s相匹配,0/1表示之前是否存在与s能匹配上的一整个子串

那么我们考虑转移:

首先我们可以枚举第i位放左括号还是右括号,如果放左括号,左右括号差值+1,否则差值-1,这些都好办,问题在于后两维!

那么显然我们要枚举原来与s匹配了多少,接下来在新放上一个括号之后,我们要考虑加上一个括号之后这一新的后缀能匹配s多长,那这一点可以kmp预处理或者暴力预处理,这里我选择暴力预处理。

于是我们只需要借助上面处理出的辅助数组进行转移即可

最后统计所有可行答案。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define mode 1000000007
#define ll long long
using namespace std;
ll f[][][][];
ll len[][];
char s[];
char p[];
int n;
int solve(int ilen)
{
for(int i=ilen;i>;i--)//??????
{
bool flag=;
for(int j=;j<i;j++)
{
if(p[ilen-i+j]!=s[j])
{
flag=;
break;
}
}
if(!flag)
{
return i;
}
}
return ;
}
int main()
{
scanf("%d",&n);
scanf("%s",s);
int l=strlen(s);
if(s[]=='(')
{
len[][]=;
}else
{
len[][]=;
}
for(int i=;i<l;i++)
{
p[i]=s[i];
p[i+]='(';
len[i+][]=solve(i+);
p[i+]=')';
len[i+][]=solve(i+);
}
f[][][][]=;
for(int i=;i<=*n;i++)//???????λ
{
for(int j=;j<=n;j++)//??????????????
{
for(int k=;k<=l;k++)//??????????????
{
for(int t=;t<=;t++)
{
if(!f[i-][j][k][t])
{
continue;
}
if(j+<=n)
{
f[i][j+][len[k][]][t|(len[k][]==l)]+=f[i-][j][k][t];
f[i][j+][len[k][]][t|(len[k][]==l)]%=mode;
}
if(j>)
{
f[i][j-][len[k][]][t|(len[k][]==l)]+=f[i-][j][k][t];
f[i][j-][len[k][]][t|(len[k][]==l)]%=mode;
}
}
}
}
}
ll ans=;
for(int i=;i<=l;i++)
{
ans+=f[*n][][i][];
ans%=mode;
}
printf("%lld\n",ans);
return ;
}

CF1015F的更多相关文章

  1. 【CF1015F】Bracket Substring(字符串DP)

    题意:给定一个只由左右括号组成的字符串s,问长度为2*n的包含它的合法括号序列方案数,答案对1e9+7取模 1≤n≤100,1≤|s|≤200 思路:暴力预处理出s的每个前缀[0..i]后加左右括号分 ...

  2. CF1015F Bracket Substring (KMP+DP)

    题目大意:给你一个长度为$n$的括号序列$T$,要求你构造一个长度为$2n$的括号序列$S$,保证这个括号序列在插入数字后一定是正确的,并且$T$是$S$的一个子串 还以为是什么纯粹的数学构造题,一通 ...

随机推荐

  1. McQueenRPC源码阅读

    1.server 2.client 3.消息格式

  2. 基于netty的一款http server

    cicada 基本功能 1.基于注解.注解扫描 2.ioc 对象管理 3.intercepter 拦截器 ref https://github.com/TogetherOS/cicada

  3. 课程9:《hibernate框架开发2016版视频》视频目录

    \第1天\视频\01_今天内容介绍.avi; \第1天\视频\02_web内容回顾.avi; \第1天\视频\03_hibernate框架概述.avi; \第1天\视频\04_什么是orm思想.avi ...

  4. 20165231 2017-2018-2 《Java程序设计》第3周学习总结

    教材学习内容总结 对象(Object):存在的具体实体,具有明确的状态和行为 类(Class):具有相同属性和行为的一组对象的集合,用于组合各个对象所共有操作和属性的一种机制 从类看对象:类定义可以视 ...

  5. 范围for语句

    C++11 新标准引入了一种更简单的for语句,这种语句可以遍历容器或其他序列的所有元素.范围for语句(range for statement)的语法形式是: for (declaration : ...

  6. 011_docker内部各系统基本工具安装

    root@nginx-56b8c64cb4-t97vb:/# cat /etc/os-release #查看linux发行版本 PRETTY_NAME="Debian GNU/Linux 8 ...

  7. 关于hostapd的调试

    对于hostapd和wpa_supplicant 的调试时,希望显示更多的调试信息. 未改动代码时,可以将hostapd 进程拉起时所跟的参数加上"-dd". 即使这样,也不能满足 ...

  8. VS2017编译LevelDB

    环境: 操作系统:Win7 x64 编译器:VS2017 需要Boost库支持,需要先将Boost库编译成为64位版本. 一.项目文件导入 1. 下载leveldb-windows,https://c ...

  9. Light OJ 1095

    题意: 给你 N 个数, 总共有 N! 种排列, 现在 要你统计前 M 个数 刚好 有K 个数 在原来的位置上 的排列个数 思路: 首先 M 中选 K C(m,k): 则 共 剩下 n - k 个数, ...

  10. 前端 ---client、offset、scroll系列

    client.offset.scroll系列   1.client系列 代码如下: <!DOCTYPE html> <html> <head> <meta c ...