热门标签 | 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


推荐阅读
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
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社区 版权所有