这题的题意就很晦涩。题意是:问有多少种方法,把字符串s划分成不重叠的子串(可以不使用完s的所有字符,但是这些子串必须不重叠),使得t串是所有这些新串的子串。譬如第一个样例,"ababa"和"aba",共有5种方法:{aba}(前3个),{aba}(后3个),{abab},{baba},{ababa}。

  先设s的长度为lena,t的长度为lenb。

  做法是:用dp[i]表示到i为止,有几种方案数,所以最终答案是dp[lena]。然后考虑转移。首先dp[i]至少等于dp[i-1]。然后考虑把包含了一个t串的a[1~i]的后缀给取出来,不妨设目前的a[1~i]为*****abc,,t是"abc",然后新增的方法数有:如果右边包含t串的是"abc",那么左边的选择有(dp[i-3]+1)种(1是左边为空串的情况),类似的,如果右边包含t串的是"*abc",那么左边是(dp[i-4]+1)。那么累和一下即是,(dp[0]+1)+(dp[1]+1)+(dp[2]+1)+...+(dp[i-lenb]+1)。显然的,dp[0] = 0。那么这个式子就可以化简为sum(dp[1~i-lenb])+i-lenb+1。sum部分可以利用前缀和优化,如果假设pre[i]是dp[1~i]的和的话,那么sum部分变为pre[i-lenb],其余部分是i-lenb+1。假设val[i]表示i这个位置开始往前,至少包含了一个t串时的位置,例如串"*****abc",val[8] = 6,串"*****abc*",val[9] = 6。理解了val数组的含义以后,我们就可以发现如果i这个位置是t串的最后一个位置的话,那么val[i] = i-lenb+1,否则呢,val[i] = val[i-1]即可。我们可以用kmp把能够处理的val直接处理出来,其余的val通过递推得到。有了val数组以后,这个dp的转移就可以完全得到了:dp[i] = dp[i-1] + pre[val[i]-1] + val[i]。然后dp的过程中维护一下前缀和即可,最后需要注意要对1e9+7取模。

  另外需要注意的是,如果说当前的串最后一个字符并不是t串的最后一个字符,例如"*****abc*",这样的话通过上面这个转移我们可以知道,右边的串也必须是以最后一个字符结尾的(实际上任何情况下右边这个串都是需要以最后一个字符结尾的,否则新增的这个字符就没有意义了,也就会出现和之前的方案重复的情况了)。这一点想清楚了,这个转移就没有任何的问题了。

  最终的代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int N = 1e5 + ;
const int mod = 1e9 + ; char a[N],b[N];
int lena,lenb,nxt[N];
int val[N];
int sum[N];
int dp[N];
void get_nxt()
{
nxt[] = ;
int j = ;
for(int i=;i<=lenb;i++)
{
while(j && b[j+] != b[i]) j = nxt[j];
if(b[j+] == b[i]) j++;
nxt[i] = j;
} j = ;
for(int i=;i<=lena;i++)
{
while(j && b[j+] != a[i]) j = nxt[j];
if(b[j+] == a[i]) j++;
if(j == lenb)
{
val[i] = i - lenb + ;
j = nxt[j];
}
}
} int main()
{
scanf("%s%s",a+,b+);
lena = strlen(a+);
lenb = strlen(b+);
get_nxt();
for(int i=;i<=lena;i++) if(!val[i]) val[i] = val[i-];
for(int i=;i<=lena;i++)
{
dp[i] = dp[i-];
if(val[i]) dp[i] = (dp[i] + sum[val[i]-] + val[i]) % mod;
sum[i] = (sum[i-] + dp[i]) % mod;
}
printf("%d\n",dp[lena]);
return ;
}

CodeForces 494B Obsessive String ——(字符串DP+KMP)的更多相关文章

  1. codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

    /** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...

  2. Codeforces 494B Obsessive String

    http://www.codeforces.com/problemset/problem/494/B 题意:给出两个串S,T,求有几种将S分成若干个子串,满足T都是这若干个子串的子串. 思路:f[n] ...

  3. [Codeforces-div.1 494B]Obsessive String

    [CF-div.1 B]Obsessive String 题目大意 两个字符串\(S,T\),求划分方案数使得一个集合中两两划分不相交且划分都包含字符串\(T\) 试题分析 kmp先求出那个位置匹配. ...

  4. HDU3689 Infinite monkey theorem 无限猴子(字符串DP+KMP)

    题目描述: 大概的意思就是根据无限猴子定理,无限只猴子坐在打字机旁瞎敲,总有一个能敲出莎士比亚文集.现在给你一个打字机和一只猴子,打字机的每个按钮(共n个)上的字母及猴子按下这个按钮的概率已知,而且猴 ...

  5. codeforces#1120C. Compress String(dp+后缀自动机)

    题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一 ...

  6. codeforces#1183H. Subsequences(字符串dp)

    题目链接: http://codeforces.com/contest/1183/problem/H 题意: 给出一个长度为$n$的字符串,得到$k$个子串,子串$s$的花费是$n-|s|$ 计算最小 ...

  7. Codeforces 235C Cyclical Quest 字符串 SAM KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html 题目传送门 -  CF235C 题意 给定一个字符串 $s$ ,多组询问,每组询问的形式为 ...

  8. [LeetCode] Scramble String 字符串 dp

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

  9. DP × KMP

    几道用到KMP的DP题: hdu 5763    hdu 3689    hdu 3336    codeforces 494B    codevs 3945 关于KMP的nx数组: 如果在本文中看见 ...

随机推荐

  1. vue 集成jTopo 处理方法

    jTopo 帮助说明网站 http://www.jtopo.com/index.html 使用例子: http://www.jtopo.com/demo/helloworld.html 不建议直接安装 ...

  2. Https请求被中止: 未能创建 SSL/TLS 安全通道

    可以参考https://www.cnblogs.com/ccsharp/p/3270344.html 和https://blog.csdn.net/baidu_27474941/article/det ...

  3. ELK日志分析系统的搭建

    一.ELK简介 ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心组件. Elasticsearch是数据存储.搜索.分析引擎,功能非常强大:Logstash是日志 ...

  4. Vscode ftp

    sftp的插件,作者是liximomo 安装插件: 在Vscode的商店中搜索sftp扩展 配置: 一般在开发项目时,总是有多个项目在同时开发.如果要为单一的项目配置的话,就需要打开此项目,快捷键ct ...

  5. 【Distributed】分布式配置中心

    一.概述 1.1 什么是分布式配置中心 常用分布式配置中心框架 二.Apollo阿波罗 2.1 Apollo特点 2.2 Apollo整体架构原理 2.3 Apollo Portol 环境搭建 Lin ...

  6. 【SQL server】SQL server基础(一)

    一.关系型数据库 关系型数据库的基本元素是二维表,这些二维表可以被独立或者通过join语句连接起来使用.主键和外键是用来连接二维表之间的主要工具 1.主键(primary key)和外键(foreig ...

  7. InnoDB全文索引

    ### 如果想了解全文索引,可以直接将本文复制到mysql的新建查询中,依次执行,即可了解全文索引的相关内容及特性. -- InnoDB全文索引 -- 建表 CREATE TABLE fts_a ( ...

  8. 为什么要用BigDecimal

    一般货币计算的时候都要用到BigDecimal类,为什么一般不适用float或者double呢? 先看一下浮点数的二进制表示: 小数 0.125 0.125 * 2 = 0.25 0 0.25 * 2 ...

  9. java线程基础巩固---多线程死锁分析,案例介绍

    之前已经学习了关于同步锁的知识,但是在实际编写多线程程序时可能会存在死锁的情况,所以这次来模拟一下死锁,并且学会用一个命令来确认是否程序已经出现死锁了,下面开始: 首先新建两个类: 此时当然得到Oth ...

  10. PHP基础知识 - 字符串处理函数

    addcslashes — 为字符串里面的部分字符添加反斜线转义字符 addslashes — 用指定的方式对字符串里面的字符进行转义 bin2hex — 将二进制数据转换成十六进制表示 chop — ...