子串 NOIP2015 D2T2 luoguP2679 字符串处理+DP
题目大意:
给定两个长度分别为 n 和 m 的字符串 A 和 B,选取 A 中的 k 个子串,使这 k 个子串按照先后顺序连接起来后等于 B 子串。
输入输出样例
首先,看题目的要求。对于这类题目要求,以及如此之小的数据范围,考虑使用动态规划。
/*------------------------加一段解释一下为什么要设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的更多相关文章
- 4560 NOIP2015 D2T2 子串
4560 NOIP2015 D2T2 子串 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 有两 ...
- Codevs 4560 NOIP2015 D2T2 子串
> 4560 NOIP2015 D2T2 子串 时间限制: 1 s 空间限制: 128000 KB 题目等级:黄金 Gold 题目描述 Description 有两个仅包含小写英文字母的字符串A ...
- 4560 NOIP2015 D2T2 子串 code vs
4560 NOIP2015 D2T2 子串 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有两个仅包含小写 ...
- 子串 [NOIP2015]
Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新 ...
- 刷题总结——子串(NOIP2015)
题目: 题目背景 NOIP2015 提高组 Day2 T2 题目描述 有两个仅包含小写英文字母的字符串 A 和 B .现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在 ...
- 【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)
[BZOJ1396]识别子串&[BZOJ2865]字符串识别(后缀自动机) 题面 自从有了DBZOJ 终于有地方交权限题了 题解 很明显,只出现了一次的串 在\(SAM\)的\(right/e ...
- bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)
bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...
- 洛谷P2679 子串 [noip2015] dp
正解:dp 解题报告: 感觉是道dp好题啊,所以就写了个题解 代码实现难度低,思维难度大,像我这种思维僵化傻逼选手只想到了爆搜+组合数学... 其实是道很妙的dp题!好趴也没有多妙主要大概是妙在想到了 ...
- nyoj 37 回文字符串 【DP】
先反向复制一个新的字符串,然后再找出最长公共子串,在用长度n减去就可以 回文字符串 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描写叙述 所谓回文字符串,就是一个字符串,从 ...
随机推荐
- andorid jar/库源码解析之Dagger/Dagger2
目录:andorid jar/库源码解析 Dagger.Dagger2: 作用: 1.用于解耦Activity和业务逻辑 2.在使用业务的时候,不需要重复编写new代码. 3.当业务变化的时候,不需要 ...
- Go中的数组切片的使用总结
代码示例 package main import "fmt" func main(){ fmt.Println("Hello, world") // 定义数组的 ...
- WCF(一)
在学习WCF之前要知道几个术语: 一:终结点 终结点由3个要素组成:契约,绑定,地址. 1.契约:契约属于一个服务公开接口的一部分.一个服务的契约,定义了服务端公开的服务方法,使用的传输协议,可访问的 ...
- 王颖奇 201771010129《面向对象程序设计(java)》第一周学习总结
<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com wangyingqi 程序 ...
- Day_09【常用API】扩展案例1_程序中使用一个长度为3的对象数组,存储用户的登录名和密码……
需求说明:实现用户注册.登陆功能: 1.程序中使用一个长度为3的**对象数组**,存储用户的登录名和密码: 例如如下格式: 登录名 密码 生日 爱好 zhangsan 1111 1998-03-15 ...
- Vulnhb 靶场系列:Jarbas1.0
靶场镜像 官网 信息收集 攻击机kali IP地址 通过nmap 进行主机发现,发现目标机IP地址 nmap -sP 192.168.227.1/24 参数说明: -sP (Ping扫描) 该选项告诉 ...
- Web(4)servlet
一.servlet.GenericServlet.HttpServlet 1.servlet具有四个生命周期方法 特性:单例模式,线程不安全,效率高 2.servletConfig接口对应根元素对应的 ...
- [hdu4670 Cube number on a tree]点分治
题意:给一个N个带权节点的树,权值以给定的K个素数为因子,求路径上节点乘积为立方数的路径条数 思路:立方数的性质是每个因子的个数为3的倍数,那么每个因子只需要保存0-2三个状态即可,然后路径就可以转化 ...
- 这份书单会告诉你,Java网络编程其实很重要
- 疑问_网址参数不同的时候改如何选择_MySQL_芬兰站
豹子安全-注入工具-疑问_网址参数不同的时候改如何选择_MySQL_芬兰站_kouvolankipparit.fi_基于联合查询_20200416 www.leosec.net 请看下列GIF视频: