Codeforces Beta Round #71 C【KMP+DP】
Codeforces79C
题意:
求s串的最大子串不包含任意b串;
思路:
dp[i]为以i为起点的子串的最长延长距离。
我们可以想到一种情况就是这个 i 是某个子串的起点,子串的长度-1就是最短,
或者这个 前面的长度 +这个i 就是答案。
所以预处理一下,以 i 为起点的最短子串距离就好了,这里利用KMP比较方便。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const int N=1e5+10; int vis[N]; char s[N]; int Next[N],lens,lenp; int dp[N]; //dp[i]为以i为起点的最长距离。 void GetNext(char *str) { int i=0,j=-1; int len=strlen(str); Next[0]=-1; while(i<len) { if(j==-1||str[i]==str[j]) Next[++i]=++j; else j=Next[j]; } } void KMP(char *p,int x) { int i=0,j=0; lenp=strlen(p); while(i<lens&&j<lenp) { if(j==-1||p[j]==s[i]) { i++;j++; } else j=Next[j]; if(j==lenp) { vis[i-lenp]=min(vis[i-lenp],lenp); j=Next[j]; } } } int main() { int n; char b[15]; scanf("%s",s); lens=strlen(s); scanf("%d",&n); memset(vis,INF,sizeof(vis)); for(int i=1;i<=n;i++) { scanf("%s",b); GetNext(b); KMP(b,i); } /* for(int i=0;i<lens;i++) printf("%d\n",vis[i]); puts(""); */ int pos=lens; dp[n]=0; for(int i=lens-1;i>=0;i--) { dp[i]=min(vis[i]-1,dp[i+1]+1); if(dp[i]>dp[pos]) pos=i; } if(pos==lens) { puts("0 0"); return 0; } printf("%d %d\n",dp[pos],pos); return 0; }