热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NOIP2015DAY2T2子串

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

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

20170522100101_14084

【数据规模与约定】 对于第1组数据&#xff1a;1<&#61;n<&#61;500&#xff0c;1<&#61;m<&#61;50&#xff0c;k&#61;1; 对于第2组至第3组数据&#xff1a;1<&#61;n<&#61;500&#xff0c;1<&#61;m<&#61;50&#xff0c;k&#61;2; 对于第4组至第5组数据&#xff1a;1<&#61;n<&#61;500&#xff0c;1<&#61;m<&#61;50&#xff0c;k&#61;m; 对于第1组至第7组数据&#xff1a;1<&#61;n<&#61;500&#xff0c;1<&#61;m<&#61;50&#xff0c;1<&#61;k<&#61;m; 对于第1组至第9组数据&#xff1a;1<&#61;n<&#61;1000&#xff0c;1<&#61;m<&#61;100&#xff0c;1<&#61;k<&#61;m; 对于所有10组数据&#xff1a;1<&#61;n<&#61;1000&#xff0c;1<&#61;m<&#61;200&#xff0c;1<&#61;k<&#61;m。

输入

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

输出

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

样例输入[复制]
样例1&#xff1a;
6 3 1
aabaab
aab

样例2&#xff1a;
6 3 2
aabaab
aab

样例3&#xff1a;
6 3 3
aabaab
aab
样例输出[复制]
样例1&#xff1a;
2

样例2&#xff1a;
7

样例3&#xff1a;
7
这道题我一开始看到也知道是dp&#xff0c;但是看到这个数据范围我就直接虚了
数组都开不下
但我暂时抛开这个东西不管&#xff0c;不计空间成本的话实际上状态是很容易出来的
首先有点基础知道这是个三维dp&#xff0c;状态f[i][j][k]代表A串前i个字符&#xff0c;已经匹配了B串j个字符&#xff0c;当前已经使用k次子串的方案数
显然貌似一个方程就出来了
对于当前的i,j来说&#xff0c;往后转移的条件显然是当前的a[i]&#61;&#61;b[j]&#xff0c;我们从最长公共子序列可以知道这一点

f[i][j][k]&#61;f[i-1][j-1][k-1]&#43;f[i-1][j-1][k]

这个式子的意思是当前的决策可以是单独成为一串&#xff0c;或者与前面的合并成一串
正如luogu里面的题解说的一样&#xff0c;这个方程的问题在于如果相等了就必须匹配进去&#xff0c;可能不使用后面也有选择&#xff0c;如果你不匹配直接沿用前面&#43;f[i-1][j][k]的话会出现重复计数的问题&#xff08;至少写完代码我是这么认为的&#xff0c;有错希望指正&#xff09;
看完题解之后发现要设两个数组f[i][j][k]与s[i][j][k]&#xff0c;第一个数组代表选或者不选当前的字符的方案数&#xff0c;第二个是必须选的方案数
为了分解问题我们先看s[i][j][k]的转移方法&#xff0c;当然前提还是a[i]&#61;b[j]
s[i][j][k]由于必须要选进去&#xff0c;则只用考虑是单独成为一串或者是与前面连在一起
注意如果是前者因为前面的状态我不知道&#xff0c;我只知道我现在是用了一个字符单独成为一串&#xff0c;前面的用没用我不知道&#xff0c;所以应该是f[i-1][j-1][k-1],代表不确定性
后者由于与前面是连在一起的所以前面的也会被使用&#xff0c;所以应该是s[i-1][j-1][k]
总的下来方程就是

s[i][j][k]&#61;f[i-1][j-1][k-1]&#43;s[i-1][j-1][k]

显然如果a[i]!&#61;b[j]的话直接s[i][j][k]就是0

接下来我们考虑f[i][j][k]的转移&#xff0c;前提还是一样的

由于我现在的决策已经变成了选或者不选的问题了&#xff0c;已经与匹不匹配无关了

如果我选择这个进行匹配的话&#xff0c;如果是使用当前的字符&#xff0c;我们就要加上一定使用这个字符的方案数s[i][j][k]&#xff0c;如果你说我选上并不匹配怎么办&#xff1f;注意如果本身不匹配那么s[i][j][k]是0&#xff0c;选上没有意义

如果我们选择不用的话&#xff0c;自然就直接由上一个状态转移过来f[i-1][j][k]

方程就是

f[i][j][k]&#61;s[i][j][k]&#43;f[i-1][j][k]

为什么我们这个没有判断说是a[i]&#61;&#61;b[j]?因为与匹配无关&#xff0c;我们关心的是选上去的方案数的贡献和不选的贡献&#xff0c;为什么我们不在s里面解决&#xff1f;因为选与不选是一个状态&#xff0c;自成一家或者与前面混合又是一个状态&#xff0c;两个状态不能混在一起&#xff01;&#xff01;

最后发现数组不够用啊&#xff0c;我们尝试滚掉一维

为什么我们能滚掉一维&#xff1f;因为在写循环的时候我们是按i作为第一维&#xff0c;而第一维i使用完之后只会对i&#43;1做出贡献&#xff0c;就是背包问题&#xff0c;于是我们就复用数组

至于滚掉一维数组后后面的循环顺序就应该倒过来&#xff0c;因为你要用之前的状态&#xff0c;如果你正向就会用到刚算好的状态造成重复&#xff08;这也是多重背包的原理&#xff09;&#xff0c;就可以覆盖前面

还是照例总结一下

这道题其实告诉我如果有多个不同的状态&#xff08;红字&#xff09;就应该尝试分开他们来进行讨论&#xff0c;不要固执于使用一个数组&#xff0c;这些状态是交融但是不完全等同的&#xff0c;应该及时分开处理

记得取模

代码在下面了&#xff1a;

1 #include
2 #include
3 using namespace std;
4 char a[100000],b[10000];
5 int f[1000][1000];
6 int s[1000][1000];const int mod&#61;1000000007;
7 int main() {
8 int n,m,k;
9 cin>>n>>m>>k;
10 for(int i&#61;1; i<&#61;n; i&#43;&#43;)cin>>a[i];
11 for(int i&#61;1; i<&#61;m; i&#43;&#43;)cin>>b[i];
12 f[0][0]&#61;1;
13 for(int i&#61;1;i<&#61;n;i&#43;&#43;){
14 for(int j&#61;m;j>&#61;1;j--){
15 for(int l&#61;k;l>&#61;1;l--){
16 if(a[i]&#61;&#61;b[j])s[j][l]&#61;f[j-1][l-1]&#43;s[j-1][l];
17 else s[j][l]&#61;0;
18 s[j][l]%&#61;mod;
19 f[j][l]&#61;f[j][l]&#43;s[j][l];
20 f[j][l]%&#61;mod;
21 //cout<
22 }
23 }
24 }
25 cout<<f[m][k];
26 return 0;
27 }

一道好题啊


转载于:https://www.cnblogs.com/saionjisekai/p/9653320.html


推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
author-avatar
钟杰辉_576
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有