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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章