[HDU 3336]Count the String[kmp][DP]
题意:
求一个字符串的所有前缀串的匹配次数之和.
思路:
首先仔细思考: 前缀串匹配.
n个位置, 以每一个位置为结尾, 就可以得到对应的一个前缀串.
对于一个前缀串, 我们需要计算它的匹配次数.
k = next [ j ]
表示前缀串 Sj 的范围内(可以视为较小规模的子问题), 前缀串 Sk 是最长的&能够匹配两次的前缀串.
这和我们需要的答案有什么关系呢?
题目是求所有前缀串的匹配次数之和, 那么可以先求前缀串 Si 在整个串中的匹配次数, 再加和.
到此, 用到了两个"分治", 一是将大规模的问题减小为小规模的问题, 二是将询问的最终结果拆分成一个个步骤, 则专注于分析核心步骤.
可设dp[ i ]为前缀串 Si 在总串中出现的次数.
dp[i] = 1;
dp[next[i]] += dp[i];
#include <cstring>
#include <cstdio>
const int MAXN = 200005;
const int MOD = 10007;
int dp[MAXN],next[MAXN];
char s[MAXN];
//46MS 1960K
void prekmp()
{
next[0] = -1;
int j = -1;
for(int i=1;s[i];i++)
{
while(j!=-1 && s[j+1]!=s[i]) j = next[j];
if(s[j+1]==s[i]) j++;
next[i] = j;
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
scanf("%s",s);
prekmp();
for(int i=0;i<n;i++) dp[i] = 1;
dp[n] = 0;
for(int i=n-1;i;i--)
{
if(next[i]!=-1) {dp[next[i]] += dp[i];dp[next[i]] %= MOD;}
}
for(int i=0;i<n;i++) {dp[n] += dp[i];dp[n] %= MOD;}
printf("%d\n",dp[n]);
}
}
还有另一种思路:
可以将前缀的匹配次数视为包含的前缀个数.
最终的问题是求s中 (设每一种前缀i包含的前缀个数Fi ) ΣFi .
dp[i]为前缀串s[0...i]包含的前缀个数的新增数目(相对于前缀串s[0...i-1]).
则
dp[i] = dp[next[i]] + 1;//1表示它本身也是新增的一个前缀
#include <cstring>
#include <cstdio>
const int MAXN = 200005;
const int MOD = 10007;
int dp[MAXN],next[MAXN];
char s[MAXN];
//62MS 1960K
void prekmp()
{
next[0] = -1;
int j = -1;
for(int i=1;s[i];i++)
{
while(j!=-1 && s[j+1]!=s[i]) j = next[j];
if(s[j+1]==s[i]) j++;
next[i] = j;
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
scanf("%s",s);
prekmp();
memset(dp,0,sizeof(int)*(n+1));
for(int i=0;i<n;i++)
{
if(next[i]!=-1)
{
dp[i] = dp[next[i]]+1;
dp[i] %= MOD;
}
else
dp[i] = 1;
}
for(int i=0;i<n;i++) {dp[n] += dp[i];dp[n] %= MOD;}
printf("%d\n",dp[n]);
} }
[HDU 3336]Count the String[kmp][DP]的更多相关文章
- hdu 3336 Count the string KMP+DP优化
Count the string Problem Description It is well known that AekdyCoin is good at string problems as w ...
- hdu 3336 Count the string -KMP&dp
It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...
- HDU 3336 Count the string ( KMP next函数的应用 + DP )
dp[i]代表前i个字符组成的串中所有前缀出现的次数. dp[i] = dp[next[i]] + 1; 因为next函数的含义是str[1]~str[ next[i] ]等于str[ len-nex ...
- HDU 3336 Count the string KMP
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3336 如果你是ACMer,那么请点击看下 题意:求每一个的前缀在母串中出现次数的总和. AC代码: # ...
- HDU 3336 Count the string(KMP的Next数组应用+DP)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3336:Count the string(数据结构,串,KMP算法)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3336 Count the string(next数组运用)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3336 Count the string 查找匹配字符串
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3336 count the string(KMP+dp)
题意: 求给定字符串,包含的其前缀的数量. 分析: 就是求所有前缀在字符串出现的次数的和,可以用KMP的性质,以j结尾的串包含的串的数量,就是next[j]结尾串包含前缀的数量再加上自身是前缀,dp[ ...
随机推荐
- HelloWorld——Cocos2d-x学习历程(二)
HelloWorld分析: 1."resource"文件夹 该文件夹主要用于存放游戏中需要的图片.音频和配置等资源文件. 2."include"和"s ...
- WinSock网络编程基础(3)server
上一篇讲的是简单的发送数据的客户端的实现.接下来讲的是如何实现收发数据服务器.这里说的服务器其实就是一个进程,它需要等待任意数量的客户端与之建立起连接,以便响应它们的请求. 服务器必须在已知的名称上监 ...
- BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )
离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...
- 搭建Hadoop集群 (一)
上面讲了如何搭建Hadoop的Standalone和Pseudo-Distributed Mode(搭建单节点Hadoop应用环境), 现在我们来搭建一个Fully-Distributed Mode的 ...
- CSS完美兼容IE6/IE7/IE8/IE9/IE10的通用方法
关于CSS对各个浏览器兼容已经是老生常谈的问题了, 网络上的教程遍地都是.以下内容没有太多新颖, 纯属个人总结, 希望能对初学者有一定的帮助. 一.CSS HACK 以下两种方法几乎能解决现今所有HA ...
- 星际反作弊2.3for-win7-xp-win8-win10
星际反作弊2.3for-win7-xp-win8-win10 下载地址 http://wj800.com/rar/scfzb.zip
- 四轴飞行器1.4 姿态解算和Matlab实时姿态显示
原创文章,欢迎转载,转载请注明出处 MPU6050数据读取出来后,经过一个星期的努力,姿态解算和在matlab上的实时显示姿态终于完成了. 1:完成matlab的串口,并且实时通过波形显示数据 2:添 ...
- break的使用例一
/* Name:break的使用例一 Copyright: By.不懂网络 Author: Yangbin Date:2014年2月21日 02:28:24 Description:本程序代码无如何含 ...
- 《Pointers On C》读书笔记(第四章 语句)
1.空语句只包含一个分号,它本身并不执行任何任务,其适用的场合是语法要求出现一条完整的语句,但并不需要它执行任何任务. 2.C语言中并不存在专门的“赋值语句”,赋值就是一种操作,在表达式内进行.通过在 ...
- JAVA并发,同步锁性能测试
测试主要从运行时间差来体现,数据量越大,时间差越明显,例子如下: package com.xt.thinks21_2; /** * 同步锁性能测试 * * @author Administrator ...