淦!这题我做了三个月啊

题目描述

有两个仅包含小写英文字母的字符串 \(A\) 和 \(B\)。

现在要从字符串 \(A\) 中取出 \(k\) 个互不重叠的非空子串,然后把这 \(k\) 个子串按照其在字符串 \(A\) 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 \(B\) 相等?

注意:子串取出的位置不同也认为是不同的方案。

输入格式

第一行是三个正整数 \(n,m,k\),分别表示字符串 \(A\) 的长度,字符串 \(B\) 的长度,以及问题描述中所提到的 \(k\),每两个整数之间用一个空格隔开。

第二行包含一个长度为 \(n\) 的字符串,表示字符串 \(A\)。

第三行包含一个长度为 \(m\) 的字符串,表示字符串 \(B\)。

输出格式

一个整数,表示所求方案数。

由于答案可能很大,所以这里要求输出答案对 \(1000000007\) 取模的结果。

题解

首先有这些变量名:

\(dp[i][j][k]\) : 表示拿\(A[i]\)与\(B[j]\)配对,配成\(K\)段的方案数,假如\(A[i]\)和\(B[j]\)配不上的话就等于\(0\)。

\(sum[i][j][k]\) : 表示\(A\)从\(1\)到\(i\),能和\(B[j]\)配成\(K\)段的方案总数(\(dp\)数组的前缀和数组),意思就是\(sum[i][j][k] = dp[1][j][k] + dp[2][j][k]...+dp[i][j][k]\)。

那么考虑单独的\(A[i]\)和\(B[j]\),存在两种情况:

第一种是\(A[i]\)和\(B[j]\)配上了,那么就又分出两种情况:

第一种是\(A[i - 1]\)和\(B[j - 1]\)也配上了,那么可以直接接在它们后面,也可以另起炉灶(为什么不用考虑\(A[i - 1]\)和\(B[j - 1]\)没接上的情况?因为没接上的话\(dp[i - 1][j - 1] = 0\),无需考虑);

第二种是\(A[i - 1]\)和\(B[j - 1]\)没配上,那我们就必须找到某个\(A[i']\)和\(B[j - 1]\)配上了,而且配成了\(k - 1\)段的地方,让\(A[i]\)与\(B[j]\)接在后面配成第\(k\)段

然后我们发现,要找到\(A[i']\)和\(B[j']\)的位置是要\(O(n)\)处理的,时间复杂度承受不住,所以我们就要用到\(sum\)数组,不用找,直接累加起前一个匹配位置\(A[i']\)的方案数就可以

第二种是配不上\(A[i]\)与\(B[j]\)配不上,那么直接赋值为\(0\)

注意:我们的\(dp\)转移方式是用\(A\)数组的每一位去尝试匹配\(B\)的某一位,只有\(B\)的上一位已经匹配过了,这一位才能继续匹配

给大佬恰代码:

#include<bits/stdc++.h>
using namespace std;
#define rint register int
int n, m, k;
int dp[2][210][210], sum[2][210][210];
char a[1010], b[250];
inline int read( void ){
int re = 0, f = 1; char ch = getchar();
while( ch > '9' || ch < '0' ){
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' ){
re = re * 10 + ch - '0';
ch = getchar();
}
return re * f;
}
int main( void ){
n = read(); m = read(); k = read();
scanf( "%s%s", a+1, b+1 );
dp[0][0][0] = 1;//一个都不匹配的方案数当然是0
int now = 0, pre = 1;
for( rint i = 1; i <= n; i++ ){
dp[now][0][0]=sum[now][0][0] = 1;
dp[pre][0][0]=sum[pre][0][0] = 1;
for( rint j = 1; j <= m; j++ ){
for( rint kk = 1; kk <= k; kk++ ){
if( a[i] == b[j] ){
dp[now][j][kk] = ( sum[pre][j - 1][kk - 1] + dp[pre][j - 1][kk] ) % 1000000007;
}
else dp[now][j][kk] = 0;
sum[now][j][kk] = ( sum[pre][j][kk] + dp[now][j][kk] ) % 1000000007; //处理前缀和
}
}
swap( now, pre );
}
cout << sum[pre][m][k];
return 0;
}

【题解】NOIP 2015 子串的更多相关文章

  1. UOJ #149 [NOIP 2015] 子串

    传送门 Solution DP+滚动数组. DP状态 \(dp[i][j][k]\): \(A\)的第\(i\)个字符和\(B\)的第\(j\)个字符匹配且该字符在第\(k\)个子串中的方案数. 转移 ...

  2. 洛谷 2679 [NOIP 2015] 子串

    题目戳这里 一句话题意 给你两个字符串A,B从A中取出K个不重合子串(顺序与在A中顺序相同)组成B,问有多少种方案? Solution 话说重打还是出各种错误也是醉了 先看题目,因为答案与A串,B串和 ...

  3. NOIP 2015 子串

    借鉴大神思路... #include<cstdio> #include<cstring> #include<cstdlib> #include<iostrea ...

  4. 4632 NOIP[2015] 运输计划

    4632 NOIP[2015] 运输计划  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题解       题目描述 Description 公元 2044 ...

  5. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  6. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  7. NOIP 2015

    Prob.1 2015 神奇的幻方 模拟就好了.(这不是noip2017的初赛题么.)代码: #include<cstdio> #include<cstring> #inclu ...

  8. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  9. Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)

    Luogu 2668 NOIP 2015 斗地主(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来 ...

随机推荐

  1. CF-1111B-Average Superhero Gang Power

    首先,对于这题我们要知道要删除一个数使平均值最大一定是删除最小的数,然后我们假设删除操作执行了i次,也就是删除最小的i个数.在已知删除操作次数之后求增加操作的次数就容易了,当然是m - i和k * ( ...

  2. CF-1066B-Heaters

    这题就是从1到n点进行遍历,对未加热的点找到最远的能加热到这个点的点,还是看代码讲吧 #include"bits/stdc++.h" using namespace std; co ...

  3. (七)spring+druid多数据源配置

    druid多数据源配置 一.druid简介 Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser. ...

  4. web压测工具http_load

    1.什么是http_loadhttp_load是一款基于Linux平台的web服务器性能测试工具,用于测试web服务器的吞吐量与负载,web页面的性能. 2.http_load的安装1)下载地址:ht ...

  5. Java ERROR JDWP Unable to get JNI 1.2 environment, jvm

    Java: ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 DWP exit erro ...

  6. 吴裕雄--天生自然 python开发学习笔记:下载python离线安装whl文件链接

    https://www.lfd.uci.edu/~gohlke/pythonlibs/

  7. RE模块(正则)

    RE模块和正则表达式 正则表达式 正则就是用来筛选字符串中的特定的内容的(只要是reg...一般情况下都是跟正则有关) re模块与正则表达式之间的关系: 正则表达式不是python独有的 它是一门独立 ...

  8. Python利用元类来控制实例创建

    问题: 改变实例创建方式,以此来实现单例模式,缓存或者其他类似的特性. 解决方法: 如果想定制化创建实例的过程,可以通过定制一个元类并以某种方式重新实现它的__call__()方法. 使用元类的单例模 ...

  9. Selenium&Pytesseract模拟登录+验证码识别

    验证码是爬虫需要解决的问题,因为很多网站的数据是需要登录成功后才可以获取的. 验证码识别,即图片识别,很多人都有误区,觉得这是爬虫方面的知识,其实是不对的. 验证码识别涉及到的知识:人工智能,模式识别 ...

  10. 每日背单词 - Jun.

    6月1日裸辞,计划休息到端午节后,这段时间玩的确实很开心,每天和朋友一起吹灯拔蜡:好不自在,可惜假期马上结束了,从今天开始恢复学习状态. 2018年6月1日 - 2018年6月14日 辞职休假 201 ...