子串
(substring.cpp/c/pas)
【问题描述】 有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个 互不重 叠 的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。

【输入格式】 输入文件名为 substring.in。 第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问 题描述中所提到的 k,每两个整数之间用一个空格隔开。 第二行包含一个长度为 n 的字符串,表示字符串 A。 第三行包含一个长度为 m 的字符串,表示字符串 B。

【输出格式】 输出文件名为 substring.out。 输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输 出答案对 1,000,000,007 取模的结果。

【思路】

DP+优化

设f[k][i][j]为已经有k段,A串匹配到i,B匹配到j的方案数,则有转移式:

f[k][i][j]=sigma{f[k-1][l][j-1]},A[i]==B[j]&&A[i-1]!=B[j-1]

= sigma{f[k-1][l][j-1]}+f[k][i-1][j-1],A[i]==B[j]&&A[i-1]==B[j-1]

前缀和优化时间,滚动数组优化空间。

【代码】

 #include<cstdio>
#include<cstring>
using namespace std; const int N = 1e3+;
const int M = +;
const int MOD = 1e9+; int f[][N][M],sum[][N][M],n,m,K;
char s1[N],s2[M]; int main() {
scanf("%d%d%d",&n,&m,&K);
scanf("%s",s1+),scanf("%s",s2+);
f[][][]=;
for(int i=;i<=n;i++) sum[][i][]=;
int x=;
for(int k=;k<=K;k++) {
x^=;
memset(sum[x],,sizeof(sum[x]));
memset(f[x],,sizeof(f[x]));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) {
if(s1[i]==s2[j]) {
f[x][i][j]=sum[x^][i-][j-];
if(s1[i-]==s2[j-]) f[x][i][j]=(f[x][i][j]+f[x][i-][j-])%MOD;
}
sum[x][i][j]=((sum[x][i][j]+sum[x][i-][j])%MOD+f[x][i][j])%MOD;
}
}
int ans=;
for(int i=;i<=n;i++)
ans=(ans+f[x][i][m])%MOD;
printf("%d",ans);
return ;
}

NOIP2015 子串 (DP+优化)的更多相关文章

  1. $[NOIp2015]$ 子串 $dp$

    \(Sol\) 不知道为啥看起来就很\(dp\)的亚子.我们关心的只有\(A\)串当前用到哪一个,\(B\)串已经匹配到哪个位置,已经匹配的被分成了多少段.所以设\(f_{i,j,k,0/1}\)表示 ...

  2. luogu2679 [NOIp2015]子串 (dp)

    设f[i][j][k][b]表示在A串第i位.这是第j组.B串第k位.i号选不选(b=0/1) 那么就有$f[i][j][k][1]=(A[i]==B[k])*(f[i-1][j-1][k][0]+f ...

  3. NOIP2015子串[序列DP]

    题目背景 无 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重 叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个 ...

  4. LOJ2424 NOIP2015 子串 【DP】*

    LOJ2424 NOIP2015 子串 LINK 题目大意是给你两个序列,在a序列中选出k段不重叠的子串组成b序列,问方案数 首先我们不考虑相邻的两段,把所有相邻段当成一段进行计算 然后设dpi,j, ...

  5. P2679 子串 DP

    P2679 子串 DP 从字符串A中取出\(k\)段子串,按原顺序拼接,问存在多少个方案使拼接的字符串与字符串B相同 淦,又是这种字符串dp 设状态\(ans[i][j][k]\)表示A串位置\(i\ ...

  6. DP 优化方法大杂烩 & 做题记录 I.

    标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...

  7. LCIS tyvj1071 DP优化

    思路: f[i][j]表示n1串第i个与n2串第j个且以j结尾的LCIS长度. 很好想的一个DP. 然后难点是优化.这道题也算是用到了DP优化的一个经典类型吧. 可以这样说,这类DP优化的起因是发现重 ...

  8. 取数字(dp优化)

    取数字(dp优化) 给定n个整数\(a_i\),你需要从中选取若干个数,使得它们的和是m的倍数.问有多少种方案.有多个询问,每次询问一个的m对应的答案. \(1\le n\le 200000,1\le ...

  9. dp优化1——sgq(单调队列)

    该文是对dp的提高(并非是dp入门,dp入门者请先参考其他文章) 有时候dp的复杂度也有点大...会被卡. 这几次blog大多数会讲dp优化. 回归noip2017PJT4.(题目可以自己去百度).就 ...

随机推荐

  1. [CSS]white-space 属性详解

    实例 规定段落中的文本不进行换行: p { white-space: nowrap } 可能的值 值 描述 normal 默认.空白会被浏览器忽略. pre 空白会被浏览器保留.其行为方式类似 HTM ...

  2. GAC write failed when upgrade with InstallShield

    在接近final-build的时候,突然发现当前版本从上一个版本upgrade的时候,需要写到GAC (Global Assembly Cache)的assambly会写失败掉.但是只会在特定的Mic ...

  3. CentOS下shell显示-bash-4.1#不显示用户名路径的解决方法

    CentOS下shell显示-bash-4.1$不显示用户名路径的解决方法 问题描述: CentOS下新增一个用户,登录进去之后shell脚本的信息如下: 而不是我们经常看到的username@hos ...

  4. linux点滴:NFS

    介绍 NFS,Network File System,网络文件系统.主要功能是通过网络让不同的主机系统间共享资源,类似于windows下的文件共享.适用于互联网中小型企业. 工作原理 客户端发送请求 ...

  5. Java学习-数组

    1.数组的是Object的直接子类,它属于“第一类对象”,但是它又与普通的java对象存在很大的不同,类名为:[I 一维数组:[I 二维数组:[[I 三维数组:[[[I 2.[代表了数组的维度,一个[ ...

  6. Oracle分析函数之FIRST_VALUE和LAST_VALUE

    FIRST_VALUE 返回组中数据窗口的第一个值 FIRST_VALUE ( [scalar_expression )OVER ( [ partition_by_clause ] order_by_ ...

  7. MVC-Html.ActionLink的几种写法

    Html.ActionLink("linkText","actionName") Html.ActionLink("linkText",&q ...

  8. TypeScript学习指南第一章--基础数据类型(Basic Types)

    基础数据类型(Basic Types) 为了搭建应用程序,我们需要使用一些基础数据类型比如:numbers,strings,structures,boolean等等. 在TypeScript中除了Ja ...

  9. 敏捷开发概述与路线(转自MBAlib)

    敏捷开发的概述 简单的说,敏捷开发是一种以人为核心.迭代.循序渐进的开发方法.在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征.换言之,就是把一个大项 ...

  10. Grails默认首页的修改

    有些人使用IDEA开发Grails,开发阶段使用Grails自带的默认首页可以方便我们开发,但是开发结束后想要修改默认的首页,如何修改呢? 1.打开grails-app 文件下conf下的UrlMap ...