BZOJ3075 : [Usaco2013]Necklace

首先对b串做kmp求出nxt数组。

设f[i][j]表示考虑了a的前i个字符,在b中匹配到了j的最长长度,按照kmp算法直接转移即可。

$ans=n-\max(f[n][j])$。

时间复杂度$O(nm)$。

 

#include<cstdio>
#include<cstring>
#define N 1010
char a[10010],b[N];int n,m,i,j,k,x,nxt[N],f[2][N],ans;
inline void up(int&a,int b){if(a<b)a=b;}
int main(){
  scanf("%s%s",a+1,b+1),n=strlen(a+1),m=strlen(b+1);
  for(i=2;i<=m;nxt[i++]=j){
    while(j&&b[j+1]!=b[i])j=nxt[j];
    if(b[j+1]==b[i])j++;
  }
  for(j=1;j<m;j++)f[0][j]=-1;
  for(i=0;i<n;i++,x^=1){
    for(j=0;j<m;j++)f[x^1][j]=-1;
    for(j=0;j<m;j++)if(~f[x][j]){
      up(f[x^1][j],f[x][j]);
      for(k=j;k&&b[k+1]!=a[i+1];k=nxt[k]);
      if(b[k+1]==a[i+1])k++;
      up(f[x^1][k],f[x][j]+1);
    }
  }
  for(j=0;j<m;j++)up(ans,f[x][j]);
  return printf("%d",n-ans),0;
}

  

posted @ 2015-10-28 00:31  Claris  阅读(344)  评论(0编辑  收藏  举报