AC通道!

题目大意:

给定两个长度分别为 n 和 m 的字符串 A 和 B,选取 A 中的 k 个子串,使这 k 个子串按照先后顺序连接起来后等于 B 子串。

 

输入输出样例

输入 #1
6 3 1
aabaab
aab
输出 #1
2
 
输入 #2
6 3 2 
abaab 
aab
输出 #2
7
 
输入 #3
6 6 3
aabaab
aab
输出 #3
7
 

首先,看题目的要求。对于这类题目要求,以及如此之小的数据范围,考虑使用动态规划。

/*------------------------加一段解释一下为什么要设0 / 1这一维---------------------------------------*/

首先定义状态f[i][j][k]代表A里前i个字符挑出k个子串组成b的前j个字符的总方案数,那答案就是f[n][m][k];

然后想怎么转移

1.a[i] == b[j]

f[i][j][k] = f[i-1][j-1][k-1]  +  f[i-1][j-1][k] + f[i-1][j][k]

考虑a[i]可以自己一个人组成子串,跟前面的A[i-1]相连组成子串和不选A[i]

2.a[i] != b[j]

f[i][j][k] = f[i-1][j][k] (那就是不选A[i])

但是,实际上, 在第一种情况中,dp[i-1][j-1][k]这样的表达是错误的。

因为这种情况要求A[i-1]必须被选中,但f[i-1][j-1][k]指的是从A的前i-1个字符中挑出k个子串组成B的前j-1个字符,并没有规定一定要选A[i-1]。所以想到要再

多加一个状态0/1表示选不选A[i]

设计状态(需要记录什么?):

1、A串匹配到哪里

2、B串匹配到哪里

3、当前已经用了多少子配串(k)

4、上一位和这一位选还是不选(会影响到k,于是必须记录)

于是,设计状态 f[i][j][p][0/1], 来表示A串匹配到 i 位, B串匹配到 j 位, 已经使用了 p 个子串,这一位选/不选的最大方案数。

然后想状态方程:

如果啊    a[i] == b[j] 

那么有  f[i][j][p][0] = f[i - 1][j][p][0] + f[i - 1][j][p][1] ;  (即为上一位选和不选之和)

f[i][j][k][1] = f[i-1][j-1][k][1](跟上一个连成一串) +  f[i-1][j-1][k-1][1](小团体,上一个用) +  f[i-1][j-1][k-1][0](小团体,上一个不用)

如果不相等,

不选的情况和上面一样:   f[i][j][p][0] = f[i - 1][j][p][0] + f[i - 1][j][p][1] ; 

对于选择的情况,两个不一样,肯定不能选 所以 f[i][j][p][1] = 0;

如此开数组,内存有点吃不消。(起码比赛的时候不敢开到8 * 107)的int数组。

观察一下状态方程,发现我们的 i  这一维, 永远都是i - 1, 也就是说,之前用过的有很大程度上是浪费的。

于是我们用 ^ 操作让这一维滚动起来。

千少万少,代码不能少

#include <bits/stdc++.h>
#define N 1010
#define M 210
#define isdigit(c) ((c)>='0'&&(c)<='9')
const int mod = (int)(1e9)+;
using namespace std; int f[][M][M][];
char a[N],b[M];
int n, m, k;
bool flag = ; inline int read(){
int x = , s = ;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -;
c = getchar();
}
while(isdigit(c)){
x = (x << ) + (x << ) + (c ^ '');
c = getchar();
}
return x * s;
} int main(){
n = read(), m = read(), k = read();
scanf("%s%s",a + , b + ); /*一定要从第一位开始,而不能从0开始,不然之后会造成数组越界*/
f[][][][] = f[][][][] = ;
for(int i = ;i <= n; i++, flag ^= ){
for(int j = ;j <= m; j++){
for(int p = ;p <= k; p++){
if(a[i] == b[j]){
f[flag][j][p][] = (f[flag^][j][p][] % mod + f[flag^][j][p][] % mod) % mod;
f[flag][j][p][] = (f[flag^][j-][p][] % mod + (f[flag^][j-][p-][] + f[flag^][j-][p-][]) % mod) % mod;
}
else{
f[flag][j][p][] = ((f[flag^][j][p][] + f[flag^][j][p][]) % mod);
f[flag][j][p][] = ;
}
}
}
}
printf("%d\n",(f[n&][m][k][] + f[n&][m][k][]) % mod);/*用n的奇偶来判断滚动维度最后是 1 还是 0*/
return ;
}

子串 NOIP2015 D2T2 luoguP2679 字符串处理+DP的更多相关文章

  1. 4560 NOIP2015 D2T2 子串

    4560 NOIP2015 D2T2 子串  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 有两 ...

  2. Codevs 4560 NOIP2015 D2T2 子串

    > 4560 NOIP2015 D2T2 子串 时间限制: 1 s 空间限制: 128000 KB 题目等级:黄金 Gold 题目描述 Description 有两个仅包含小写英文字母的字符串A ...

  3. 4560 NOIP2015 D2T2 子串 code vs

    4560 NOIP2015 D2T2 子串  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 有两个仅包含小写 ...

  4. 子串 [NOIP2015]

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

  5. 刷题总结——子串(NOIP2015)

    题目: 题目背景 NOIP2015 提高组 Day2 T2 题目描述 有两个仅包含小写英文字母的字符串 A 和 B .现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在 ...

  6. 【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)

    [BZOJ1396]识别子串&[BZOJ2865]字符串识别(后缀自动机) 题面 自从有了DBZOJ 终于有地方交权限题了 题解 很明显,只出现了一次的串 在\(SAM\)的\(right/e ...

  7. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

  8. 洛谷P2679 子串 [noip2015] dp

    正解:dp 解题报告: 感觉是道dp好题啊,所以就写了个题解 代码实现难度低,思维难度大,像我这种思维僵化傻逼选手只想到了爆搜+组合数学... 其实是道很妙的dp题!好趴也没有多妙主要大概是妙在想到了 ...

  9. nyoj 37 回文字符串 【DP】

    先反向复制一个新的字符串,然后再找出最长公共子串,在用长度n减去就可以 回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 所谓回文字符串,就是一个字符串,从 ...

随机推荐

  1. 状态压缩DP(大佬写的很好,转来看)

    奉上大佬博客 https://blog.csdn.net/accry/article/details/6607703 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的 ...

  2. 纯django开发最完美博客

    2020年5月打造最时尚博客系统教程 为了学习速度,集中精力学习django和博客开发, 没有使用其它框架,也没有使用css预处理等 这样学起来最方便, 博客前后端都完成, www.duanshuil ...

  3. Nginx读书笔记三----资源分配

    1.内存及磁盘资源分配 1.1 在磁盘中存储HTTP请求体 语法: client_body_in_file_only on|clean|off; 默认: client_body_in_file_onl ...

  4. 线段树 B数据结构 牛客练习赛28

    链接:https://ac.nowcoder.com/acm/contest/200/B来源:牛客网 题目描述 qn姐姐最好了~     qn姐姐给你了一个长度为n的序列还有m次操作让你玩,     ...

  5. vue项目兼容ie

    一.兼容ES6 Vue 的核心框架 vuejs 本身,以及官方核心插件(VueRouter.Vuex等)均可以在 ie9 上正常使用.但ie不兼容es6,所以需要安装插件将“Promise”等高级语法 ...

  6. Web前端基础第一天

    Web标准的构成 结构:结构对于网页元素进行整理和分类,现阶段主要学的是html 表现:表现用于设置元素的板式.颜色.大小等外观样式,主要指的是CSS 行为:行为是指网页模型的定义及交互的编写,现阶段 ...

  7. HTTP接口测试

    HTTP接口测试 1.1 get接口 请求URL http://api.nnzhp.cn/api/user/stu_info 请求方式 get 请求参数 参数名 必选 类型 说明 stu_name 是 ...

  8. Coursera课程笔记----计算导论与C语言基础----Week 2

    计算机的历史与未来(Week 2) 计算机历史 早期计算机:手工计算器➡️机械计算器➡️计算机原型 现代计算机:电子管计算机➡️晶体管计算机➡️集成电路计算机➡️超大规模集成电路 早期的手工计算辅助工 ...

  9. 就没有我遇不到的报错!java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/filter/Filter

    本来准备用HBase的Bulkload将HDFS的HFile文件导入到HBase的myuser2表中,用的是yarn jar的命令 yarn jar /export/servers/hbase-1.2 ...

  10. 数组的操作。1,JS数组去重。2,把数组中存在的某个值,全部找出来。3在JS数组指定位置插入元素。。。

    1,数组去重 let arr = [1,2,3,4,5,6,1,2,3,'a','b','a']; let temp = []; // 作为存储新数组使用 for(let i = 0; i < ...