【好题】序列自动机+dp求LCS——hdu6774

这个题意转化下,其实是 给两个串 A,B,给1e5组询问:求A[l..r]和B的LCS

由于B的len很小,只有20,所以我们考虑预处理A,求出A的序列自动机,然后在B上进行dp

dp[i,j]表示B[1..i]已经匹配了j位的最短的A[l..r]前缀,这样是很好转移的

#include<bits/stdc++.h>
using namespace std;
#define N 200005

int n,m,nxt[N][26],pos[26];
char s[N],t[N];

int main(){
    int T;cin>>T;
    while(T--){
        cin>>(s+1)>>(t+1);
        n=strlen(s+1);
        m=strlen(t+1);
        
        for(int i=0;i<26;i++)pos[i]=n+1;
        for(int i=n;i>=0;i--){
            for(int j=0;j<26;j++)nxt[i][j]=pos[j];
            if(i)pos[s[i]-'a']=i;
        }     
        
        int q;cin>>q;
        while(q--){
            int l,r,mx=0;
            scanf("%d%d",&l,&r);
            int f[30][30];
            memset(f,0x3f,sizeof f);
            for(int i=0;i<=m;i++)f[i][0]=l-1;
            
            for(int len=1;len<=m;len++){
                for(int j=len;j<=m;j++){
                    f[j][len]=f[j-1][len];
                    if(f[j-1][len-1]<=r)
                        f[j][len]=min(f[j][len],nxt[f[j-1][len-1]][t[j]-'a']);
                }
            }
            
            for(int i=1;i<=m;i++)
                if(f[m][i]<=r)mx=i;
            
            cout<<(r-l+1)+m-2*mx<<'\n'; 
        }
    }
} 

 

posted on 2020-07-24 22:03  zsben  阅读(163)  评论(0编辑  收藏  举报

导航