[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[ ...
随机推荐
- Asp.net的对Excel文档的导入导出操作
刚刚初入职场,在休闲的时间写下了项目中用到的对Excel文档操作的方法以及总结,多的不说,直接上代码 public static void CreateExcel(DataSet ds, string ...
- SQL Server 使用ROW_NUMBER()进行分页
代码示例: WITH domain AS(SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) ids,* FROM dbo.DomainInfo) SELECT * ...
- 关于使用由CA机构(EJBCA)颁发的证书实现SLLSocket双向认证服务端报null cert chain的解决方案
在 SSLSocket实现服务端和客户端双向认证的例子 文章中最后提到使用keytool.exe的自签证书实现双向认证可以,但是使用ejbca生成证书实现SLL Socket的双向认证是服务端老是报错 ...
- 一键搞定Java桌面应用安装部署 —— exe4j + Inno Setup 带着JRE, 8M起飞
转载自:http://www.blogjava.net/huliqing/archive/2008/04/18/193907.html 对于作Java桌面应用来说,比较烦人的就是安装部署问题,客户端是 ...
- Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (三) —— SharePreferences
除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息.其存储位置在/data ...
- c# 小数的处理
数值类型处理小数 1.Math.Round(x) 四舍五入 Math.Round(0.4) 0 Math.Round(-1.7) -2 2.Math.floor(x) 小于等于 x, ...
- ASP.NET MVC View向Controller传值方式总结
1:QueryString传值1)也可以使用new{}来为form的action增加querystring2)在controler里使用Request.QueryString["word&q ...
- ROS中编辑文件命令行工具rosed
rosed是rosbash套件中的一个,它允许我们通过包名直接编辑包中的文件,而不是输入包的全部路径. 用法: rosed [package_name] [filename] 例如: rosed ro ...
- C学习之结构体
结构体(struct) 结构体是由基本数据类型构成的.并用一个标识符来命名的各种变量的组合,结构体中可以使用不同的数据类型. 1. 结构体说明和结构体变量定义 在Turbo C中, 结构体也是一种数据 ...
- 用U盘和iso镜像文件重装系统
工具: 1.硬件: 容量最好在2.5G以上u盘(比如这次是2.3G的winows_7_32位_中文专业版ISO,我的U盘容量是不到8G). 2.软件: a.Ultraiso软件,来制作u盘启动项 b. ...