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;
}






posted @ 2013-06-03 22:36  heaventouch  阅读(87)  评论(0编辑  收藏  举报