子串
(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. Oracle分析函数之LEAD和LAG

    LAG 访问结果集中当前行之前的行 LAG (value_expr [,offset] [,default])OVER ( [ partition_by_clause ] order_by_claus ...

  2. JLink软件升级到4.92之后,Jlink不能用了

    JLink软件升级到4.92之后,Jlink不能用了                                                       情景描述: Jlink软件升级到4.9 ...

  3. C# zip/unzip with DotNet framework 4.5

    add reference System.IO.Compression.FileSystem public class ZipHelper { public static string UnZip(s ...

  4. C# 操作mongodb 分组

    c#操作mongodb的分组的简单例子: 1.首先要下载c#对应的mongodb驱动,官方下载地址:https://github.com/mongodb/mongo-csharp-driver/rel ...

  5. hdu 4267

    一个很不错的题: 刚刚看到这个题目就感觉要用线段树或者树状数组,但是有感觉有点不同: 敲了一发简单的线段树之后果断的T了: 网上一搜题解,发现要用55颗线段树或者树状数组: 一共有k种树,然后每种树根 ...

  6. [转贴]超级懒汉编写的基于.NET的微信SDK

    一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的xml消息在组装成实体类,所以会比较臃肿,现 ...

  7. C#博文搜集

    1. abstract (抽象类) 参考1 2. interface (接口) 参考1 3. 委托 C#委托学习

  8. win8.1中如何获得管理员权限步骤

    按WIN+R,运行对话框中输入gpedit.msc,开启组策略, 然后一步步地在"计算机配置"-"Windows 设置"-"安全设置"-&q ...

  9. C# :XML和JSON互转

    我们一般在用JSON或者XML作为数据交换的时候,可能定义一个没有真正意义方法的类,其实就是一个关于属性的数据结构,如果对于这种情况,可以将这个类对象作为中介,然后利用C#提供的序列化和反序列化的方法 ...

  10. C​+​+​构​造​函​数​,​复​制​构​造​函​数​和​析​构​函​数​专​题

    链接:http://wenku.baidu.com/view/d9316c0e52ea551810a6872a.html 本文作者:黄邦勇帅本文是学习 C++中的最基本的内容,因此学习 C++就应全部 ...