给定字符串 A,B,要求从 A 中取出互不重叠的 k 个非空子串,按照出现顺序拼起来后等于 B。求方案数。n ≤ 1000,m ≤ 200。


主要是状态的转移。先设计出$f_{i,j,k}$表长度$B_j$分了$k$段很好想,但是发现并不容易转移。

主要瓶颈在于当枚举了状态$f_{i,j,k}$ 的时候加入可以匹配($A_i=B_j$),怎么从前面$A_1\sim A_{i-1}$里找出$k-1$块的$j-1$的方案数。(注意下面几行都是基于当前$A_i=B_j$这个条件的)

发现这个是可以叠加的,也就是$f_{i,j,k}$可以继承$f_{i-1,j,k}$的所有方案,那么只要不断继承,像滚雪球一样,求$f_{i,j,k}$直接就从$f{i-1,j-1,k-1}$来推就好了。

第二个问题是,怎么处理拼接。如果枚举一段子串去匹配显然不太可做,发现拼接过程实际就是强制$i-1$处被选入了$k$个块内,然后和$i$位一合并,就完成了拼接。

于是,为了知道$i-1$强制被选了的情况下有多少种$k$个块的方案,故再添加一维$0/1$表示是否被选。

这下就可以推了。

具体可以参见代码(我用了顺推格式)。注意滚动。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,M=+,P=1e9+;
int f[][M][M][],now;
int n,m,l;
char s[N],t[M];
inline void add(int&A,int B){A+=B;A>=P&&(A-=P);}
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m),read(l);
scanf("%s",s+),scanf("%s",t+);
f[now=][][][]=;
for(register int i=;i<n;++i,now^=){
for(register int j=;j<=m;++j){
for(register int k=;k<=l;++k){
add(f[now^][j][k][],f[now][j][k][]),add(f[now^][j][k][],f[now][j][k][]);
if(s[i+]==t[j+])
add(f[now^][j+][k+][],f[now][j][k][]),
add(f[now^][j+][k+][],f[now][j][k][]),
add(f[now^][j+][k][],f[now][j][k][]);
// printf("%d %d %d %d %d\n",i,j,k,f[now][j][k][0],f[now][j][k][1]);
f[now][j][k][]=f[now][j][k][]=;
}
}
}
printf("%d\n",(f[now][m][l][]+f[now][m][l][])%P);
return ;
}

思路总结:1.继承方案,方便统计。2.子串问题中拼接可以设计0/1状态表示末尾有没有被选,这样可以直接和后面的东西合并

loj2424 「NOIP2015」子串[字符串DP]的更多相关文章

  1. LG2679 「NOIP2015」子串 线性DP

    问题描述 LG2679 题解 设\(opt[i][j]\)代表A串前\(i\)个,匹配\(B\)串前\(j\)个,选择了\(k\)个子串的方案数. 转移用前缀和优化一下. \(\mathrm{Code ...

  2. NOIP2015Day2T2子串(字符串dp)

    又被“if(a=b)”坑了QAQ...写C++还是得开Warning,这么久了pascal还没改过来咋回事啊QWQ 题目大意就不说了OWO 网上的题解都不怎么看得懂啊...好像写得都很乱?还是我太sb ...

  3. Luogu P2679 子串(字符串+dp)

    P2679 子串 题意 题目描述 有两个仅包含小写英文字母的字符串\(A\)和\(B\). 现在要从字符串\(A\)中取出\(k\)个互不重叠的非空子串,然后把这\(k\)个子串按照其在字符串\(A\ ...

  4. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

  5. 【LOJ】#2065. 「SDOI2016」模式字符串

    题解 按秩合并怎么清数组对我来说真是世纪性难题 我们很熟练地想到点分,如果我们认为某个点到重心是正着读的,由于它的深度固定,它的串也是固定的,我们只要预处理出所有长度正着重复的串,反着重复的串,和它们 ...

  6. 「洛谷5017」「NOIP2018」摆渡车【DP,经典好题】

    前言 在考场被这个题搞自闭了,那个时候自己是真的太菜了.qwq 现在水平稍微高了一点,就过来切一下这一道\(DP\)经典好题. 附加一个题目链接:[洛谷] 正文 虽然题目非常的简短,但是解法有很多. ...

  7. 逛公园「NOIP2017」最短路+DP

    大家好我叫蒟蒻,这是我的第一篇信竞题解blog [题目描述] 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园 ...

  8. BZOJ1369/LG4395 「BOI2003」Gem 树形DP

    问题描述 LG4395 BZOJ1369 题解 发现对于结点 \(x\) ,其父亲,自己,和所有的孩子权值不同,共 \(3\) 类,从贪心的角度考虑,肯定是填 \(1,2,3\) 这三种. 于是套路树 ...

  9. LG3205/BZOJ1996 「HNOI2010」合唱队 区间DP

    区间DP 区间DP: 显然是一个区间向左右拓展形成的下一个区间,具有包含关系,所以可以使用区间DP. 状态设计: 考虑和关路灯一样设计状态 因为不知道当前这个区间是从哪个区间拓展而来,即不知道这个区间 ...

随机推荐

  1. pramfs安装

    1. 拷贝 linux-3.11 pramfs-1.5.0-3.11 pramfs-Tools 到电脑中(我是新建目录linux中) 2.解压 3.cd pramfs-1.5.0-3.11/ 4.将p ...

  2. Redis二进制反转算法分析

    在 redis 源码中 dictScan 算法中用到了用到了非常经典的二进制反转算法,该算法对二进制的反转高效而实用,同时对于理解位运算也有非常大的帮助.先呈现源码: /* Function to r ...

  3. Loj 2230. 「BJOI2014」大融合 (LCT 维护子树信息)

    链接:https://loj.ac/problem/2230 思路: 设立siz数组保存虚点信息,sum表示总信息 维护子树信息link操作和access操作需要进行一些改动 可参考博客:https: ...

  4. ubuntu linux环境下安装配置jdk和tomcat

    关于linux搭建服务器,ubuntu中jdk和tomcat的安装和配置 一.jdk的安装配置 1:去官网下载好自己需要的版本,注意,linux压缩文件通常以tar.gz结尾,别下载错了.本次我下载安 ...

  5. [转帖]方正数码发布基于龙芯3A3000系列整机

    方正数码发布基于龙芯3A3000系列整机 http://www.loongson.cn/news/company/730.html 方正数码也出过龙芯相关的服务器和PC笔记本等 发布时间:2019-0 ...

  6. oracle -- 查询执行计划,判读查询语句优劣

    以oracle的scott账户:找到员工表中薪水大于本部门平均薪水的员工为例 多表查询方式: select e.empno, e.ename, e.sal, d.avgsal from emp e, ...

  7. java注解类型的aop

    import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import org.aspectj.la ...

  8. 剑指offer10:2*1的小矩形横着或者竖着去覆盖2*n的大矩形,总共有多少种方法?

    1. 题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 2.思路和方法 思路:(下面说到的x*y的矩形,x是宽 ...

  9. And Reachability CodeForces - 1169E (有向图可达性)

    大意: 给定序列$a$, 对所有的a[i]&a[j]>0, 从$i$向$j$连一条有向边, 给出$m$个询问$(x,y)$, 求是否能从$x$到达$y$. 裸的有向图可达性, 有向图可达 ...

  10. List 集合 一行4个排序

    List<string> list = new List<string>(); ; i < ; i++) { list.Add(i.ToString()); } int ...