#71 C
来源:互联网 发布:上海谷歌优化公司 编辑:程序博客网 时间:2024/05/15 03:07
题目意思是在给定主串中找一个连续的子串,使其不包含任何完整的boring串,输出其长度和起始位置。
这道题做得很失败。。。一开始就只想到用kmp匹配来标记好boring串的位置,设了4个状态,敲了180+行,结果还是wa。最后看了某牛的代码才知道可以用dp来做,其中dp[i]表示第i个下标起可以得到的最长子串长度,l[i]用来记录在第i个下标是否有boring串以其为起点,有则为其长度,反之是inf。最后从后往前扫一遍即可。dp方程为:
len1 为主串长度
dp[len1]=0;
for i=len1-1;i>=0;i--
dp[i]=min(l[i]-1,dp[i]+1);
以下是代码:
- #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=101010;
const int N=100; - int min(int a,int b) {return a<b?a:b;}
const int inf=1<<29;
char str[M],w[N];
int l[M],dp[M];
int n; - int main()
{ - while(scanf("%s",str)==1)
{
int len1=strlen(str);
int i,j,k;
int len2;
- for(i=0;i<len1;i++)
l[i]=inf;
- scanf("%d",&n);
- for(i=0;i<n;i++)
{
scanf("%s",w);
int len2=strlen(w);
for(j=0;j<=len1-len2;j++)
{
if(l[j]<=len2) continue;
for(k=0;k<len2 && w[k]==str[k+j];k++);
if(k==len2) l[j]=len2;
}
}
int ansx=len1;
dp[len1]=0;
- for(i=len1-1;i>=0;i--)
{
dp[i]=min(l[i]-1,dp[i+1]+1);
if(dp[ansx]<dp[i]) ansx=i;
}
- if(ansx==len1) ansx=0;
printf("%d %d/n",dp[ansx],ansx);
}
return 0;
}