标签:
1 4 abab
6
题意:求一个串中所有的前缀各自在串中出现次数的和。
分析:先来看看一个例子
i 1 2 3 4 5 6
str[i] a b a b a b
next[i] 0 0 1 2 3 4
next[i]=j; 表示从1----j 和 i-j+1----i这一段是相同的,利用next数组,依次推导
例如: i=5时 ababa 所包含的 前缀数 等于 以第3个a结尾的前缀数(即ababa本身) + (next[5]=3)str[3]所包含的前缀数量(即aba包含的前缀数量)
于是可以得到递推方程 dp[j]=dp[next[j]]+1 dp[0]=0;
对于这个例子,可以有:
dp[1]=dp[n[1]]+1=1; a
dp[2]=dp[n[2]]+1=1; ab
dp[3]=dp[n[3]]+1=2; a aba
dp[4]=dp[n[4]]+1=2; ab abab
dp[5]=dp[n[5]]+1=3; a aba ababa
dp[6]=dp[n[6]]+1=3; ab abab ababab
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
char s[222222];
int n;
int nt[222222];
int dp[222222];
void getnext()
{
int k=-1,j=0;
nt[0]=-1;
while(j<n)
{
if(k<0 || s[j]==s[k])
{
j++;
k++;
nt[j]=k;
}
else
k=nt[k];
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%s",s);
getnext();
// for(int i=0;i<=n;i++)
// cout<<nt[i]<<" ";
// cout<<endl;
for(int i=1;i<=n;i++) dp[i]=1;
dp[0]=0;
int ans=0;
for(int i=1;i<=n;i++)
{
dp[i]=dp[nt[i]]+1;
ans=(ans+dp[i])%10007;
}
printf("%d\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu 3336 Count the string KMP+DP
标签:
原文地址:http://blog.csdn.net/wust_zjx/article/details/47605527