Longest subsequence【思维+序列自动机】

题意:

给出两个字符串 \(s\)\(t\),求 \(s\) 中字典序严格大于串 \(t\) 的子序列的最长的长度。
题目链接:https://nanti.jisuanke.com/t/41395

分析:

先用序列自动机,处理出一个数组:\(nxt[i][j]\),表示位置 \(i\) 后面的最近的字母 \(j\) 的位置。那么,对 \(s\) 串,有两种选择:
1.选择比 \(t[i]\) 大的,则剩下的都可以选;
2.选择跟 \(t[i]\) 一样的,那么就要一直向后取,直到取完;

代码:

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+6;
char A[N],B[N];
int now[30],nxt[N][30];
void init(char s[],int len)
{
    memset(now,-1,sizeof(now));
    for(int i=len-1;i>=0;i--)
    {
        for(int j=0;j<26;j++)
            nxt[i][j]=now[j];
        now[s[i]-'a']=i;
    }
}
int main()
{
    int n,m,cnt=0;
    scanf("%d%d",&n,&m);
    scanf("%s",A);
    scanf("%s",B);
    init(A,n);
    int ans=-1;
    for(int i=B[0]-'a'+1;i<26;i++)
    {
        if(now[i]==-1) continue;
        ans=max(ans,n-now[i]);
    }
    if(now[B[0]-'a']==-1)//
    {
        printf("%d\n",ans);
        return 0;
    }
    int start=now[B[0]-'a'];
    for(int i=1;i<m;i++)
    {
        for(int j=B[i]-'a'+1;j<26;j++)
        {
            if(nxt[start][j]==-1) continue;
            ans=max(ans,n-nxt[start][j]+i);
        }
        if(nxt[start][B[i]-'a']==-1)
            break;
        start=nxt[start][B[i]-'a'];
        if(i==m-1&&start<n-1)
            ans=max(ans,n-start+i);
    }
    printf("%d\n",ans);
    return 0;
}

原文链接: https://www.cnblogs.com/1024-xzx/p/13221923.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    Longest subsequence【思维+序列自动机】

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/361184

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午1:41
下一篇 2023年3月2日 下午1:41

相关推荐