KMP算法

先来个模版:(P3375)

#include<cstdio>
#include<cstring>
const int N=1000010;
char a[N],b[N];
int lena,lenb,next[N];
void init()
{
    int j=0;next[1]=0;
    for(int i=2;i<=lenb;i++)
    {
        while(j&&b[j+1]!=b[i]) j=next[j];
        if(b[j+1]==b[i]) j++;
        next[i]=j;
    }
}
void sovle()
{
    int j=0;
    for(int i=1;i<=lena;i++)
    {
        while(j&&b[j+1]!=a[i]) j=next[j];
        if(b[j+1]==a[i]) j++;
        if(j==lenb) printf("%d\n",i-lenb+1);
    }
}
int main()
{
    scanf("%s %s",a+1,b+1);
    lena=strlen(a+1),lenb=strlen(b+1);
    init();
    sovle();
    for(int i=1;i<=lenb;i++) printf("%d ",next[i]);
    return 0;
}
模版

接下来是题:

一:51nod 1277 字符串中的最大值

求个next数组,然后dp;

#include<cstdio>
#include<cstring>
const int N=100010;
char map[N];
int next[N];
int len;
long long ans[N];
void init()
{
    int j=0;next[1]=0;
    for(int i=2;i<=len;i++)
    {
        while(j&&map[j+1]!=map[i]) j=next[j];
        if(map[j+1]==map[i]) j++;
        next[i]=j;
     }
}
int main()
{
    scanf("%s",map+1);
    len=strlen(map+1);
    init();
//    for(int i=1;i<=len;i++) printf("%d ",next[i]);
    long long maxx=0;
    for(int i=len;i>=1;i--)
    {
        ans[i]++;
        ans[next[i]]+=ans[i];
        if(maxx<ans[i]*i) maxx=ans[i]*i;
    }
    printf("%lld",maxx);
    return 0;
}
1277 字符串中的最大值

二:bzoj 3670: [Noi2014]动物园

同上,关键是dp方程;

#include<cstdio>
#include<cstring>
const int N=1000010;
const int mod=1e9+7;
char map[N];
int next[N],num[N],len=0;
long long ans;
inline void getnext()
{
    int j=0;next[1]=0;
    for(int i=2;i<=len;i++)
    {
        while(j&&map[j+1]!=map[i]) j=next[j];
        if(map[j+1]==map[i]) j++;
        next[i]=j;
        num[i]=num[j]+1;
    }
}
inline void getnum()
{
    int j=0;
    for(int i=2;i<=len;i++)
    {
        while(j&&map[j+1]!=map[i]) j=next[j];
        if(map[j+1]==map[i]) j++;
        while(j<<1>i) j=next[j];
        ans=(ans*(num[j]+1))%mod;
    }
    printf("%lld\n",ans);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(next,0,sizeof(next));
        memset(map,0,sizeof(map));
        memset(num,0,sizeof(num));
        len=0;
        num[1]=1;
        scanf("%s",map+1);
        len=strlen(map+1);
        getnext();
        //for(int i=1;i<=len;i++) printf("%d ",next[i]);
        ans=1;
        getnum();   
//      for(int i=1;i<=len;i++) printf("%d ",num[i]);    
         
    }
     
    return 0;
}
3670: [Noi2014]动物园

总结:kmp上来就是打个next数组表,然后推dp方程;

这里推荐个csdn博客:关于KMP算法

posted @ 2017-11-05 21:18  12fs  阅读(146)  评论(0编辑  收藏  举报