标签:
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