hdu 3336 Count the string KMP+DP
//KMP+DP想了一段时间都没想出来有DP思想...杯具
/*
求给定字符串含前缀的数量
abab
前缀为
a
ab
aba
abab
abab中共有六个子串是前缀a a ab ab aba abab
所以答案为 6
KMP+DP dp[i]:以c[i]结尾串的子串总共含前缀的数量
如串 a b a b a b a
next[i] -1 0 0 1 2 3 4 5
其中 dp[0]=0,
dp[1]=1,即a
dp[2]=1,即ab
dp[3]=2,即a,aba
dp[4]=2,即ab,abab
dp[5]=3,即a,aba,abab
如此类推
*/
//31MS 1984K 699 B C++ #include<stdio.h> #define N 200005 int next[N]; int dp[N]; int Max(int a,int b) { return a>b?a:b; } int find(char c[],int n) { int i=0,j=-1; next[0]=-1; while(i<n){ if(j==-1 || c[i]==c[j]){ i++;j++;next[i]=j; } else j=next[j]; } //KMP
for(i=1;i<=n;i++) dp[i]=1; dp[0]=0; int sum=0; for(i=1;i<=n;i++){ //DP dp[i]+=dp[next[i]]; sum+=dp[i]; sum%=10007; } return sum; } int main(void) { int t,n; char c[N]; scanf("%d",&t); while(t--) { scanf("%d",&n); scanf("%s",c); printf("%d\n",find(c,n)); } return 0; }
由于数据弱,直接暴力也行= =!
#include<stdio.h> #define N 10007 int main(void) { int t,n; char c[200005]; scanf("%d",&t); while(t--) { scanf("%d",&n); int sum=n%N; scanf("%s",c); int i,j; for(i=1;i<n;i++) if(c[i]==c[0]){ for(j=i;j<n;j++) if(c[j]!=c[j-i]) break; sum+=j-i; sum%=N; } printf("%d\n",sum); } return 0; }