#KMP,dp#洛谷 3426 [POI2005]SZA-Template

题目

给定一个字符串(S),字符串可以理解成一条每个字母代表一种颜色的线段,
找到一个长度最小的串(T),使得在若干位置放置(T)后使得字符串被完全覆盖


分析

显然它要么取(i),要么取(dp[fail[i]])可以使得答案尽量短,
那么判断一下如果当前位置如果能有交集那么用(dp[fail[i]])更新答案


代码

#include <cstdio>
#include <cstring>
#define rr register
using namespace std;
const int N=500011; char s[N];
int fail[N],dp[N],last[N],n;
signed main(){
	scanf("%s",s+1),n=strlen(s+1);
	for (rr int i=2,j=0;i<=n;++i){
		while (j&&s[i]!=s[j+1]) j=fail[j];
		if (s[i]==s[j+1]) ++j;
		fail[i]=j;
	}
	dp[1]=last[1]=1;//NOTICE
	for (rr int i=2;i<=n;++i){
		dp[i]=i;
		if (last[dp[fail[i]]]>=i-fail[i]) dp[i]=dp[fail[i]];
		last[dp[i]]=i;
	}
	return !printf("%d",dp[n]);
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14109941.html