The Preliminary Contest for ICPC Asia Xuzhou 2019 M. Longest subsequence(思維+序列自動機)

序列自動機跑s串
假設k爲s和t相同的長度,初始時相同長度爲0
取s串中大於t[i]的最左邊的位置,用n-tmp+1+i-1更新答案,tmp是最左端的位置
然後去t[i]相等的位置,走到下一位,如果下一位的位置不存在或者在tmp的右邊,跳出循環即可。
最後就是s串中找出了一個和t串相同的串,之後的長度只要不爲0,也是可以用來更新答案的。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int INF=0x3f3f3f3f;

int up[30],nxt[maxn][27];
char s[maxn],t[maxn];
int n,m;

void getNext()
{
    memset(up,INF,sizeof(up));
    for (int i=n;i>=0;i--) {
        for (int j=0;j<=25;j++) {
            nxt[i][j]=up[j];
        }
        if (i!=0) {
            up[s[i]-'a']=i;
        }

    }
}

int main()
{
    scanf("%d%d",&n,&m);
    scanf("%s",s+1);
    scanf("%s",t+1);
    int ans=-1;
    getNext();

    int tmp=INF;
    int loc=0;
    for (int i=1;i<=m;i++) {
        tmp=INF;
        for (int j=t[i]-'a'+1;j<=25;j++) {
            tmp=min(nxt[loc][j],tmp);
        }
        if (tmp!=INF) {
            ans=max(ans,n-tmp+1+i-1);
        }
        if (nxt[loc][t[i]-'a']==INF||nxt[loc][t[i]-'a']>tmp) {
            break;
        }
        else {
            loc=nxt[loc][t[i]-'a'];
        }

        if (i==m && m+n-loc>m) {
            ans=max(ans,m+n-loc);
        }
    }
    printf("%d\n",ans);
    return 0;
}
/*
8 3
aabcdccc
abc
ans=7
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章