BM算法总结

BM算法,可以求一个数列的最短递推式。
采用增量法,依次考虑每个数:
若在这个位置上正确,则忽略;
否则,类似拉格朗日插值法,找一个满足在前面位置都为0,这个位置上不为0的递推式,进行修补。
每当我们遇到一个这样的位置时,我们都可以得到一个这样的递推式:用目前的递推式,在0位置(即这个位置上),增加一个-1。相当于积累了一个“经验”。
这样,我们在所有的“经验”中,找到一个,并在它的前面补0,相当于移位。
若有多个,取补0后长度最小的。
时间复杂度:\(O(n(n+m))\)。(n为递推式长度,m为输入长度)。
代码:

int BM(int sz[10010],int n)
{
	int m=0;
	for(int i=1;i<=n;i++)
	{
		cd[i]=inf;
		int he=(md-sz[i])%md;
		for(int j=1;j<=m;j++)
			he=(he+1ll*ans[j]*sz[i-j])%md;
		if(he==0)
			continue;
		int ny=ksm(he,md-2);
		sb[i][0]=(md-ny)%md;
		for(int j=1;j<=m;j++)
			sb[i][j]=1ll*ans[j]*ny%md;
		cd[i]=m;int mi=inf,wz;
		for(int j=0;j<i;j++)
		{
			int t=cd[j]+(i-j);
			if(t<=mi)
				mi=t,wz=j;
		}
		for(int j=0;j<=cd[wz];j++)
			ans[i-wz+j]=(ans[i-wz+j]-1ll*sb[wz][j]*he%md+md)%md;
		if(mi>m)m=mi;
	}
	return m;
}
posted @ 2020-02-28 18:40  lnzwz  阅读(578)  评论(0编辑  收藏  举报