2020杭电多校第二场 1012.String Distance

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6774

题意:给你两个字符串 A,B|A|105,|B|20|A|≤105,|B|≤20,每次询问 A 串的一个子串 A[L]...A[R],问该子串通过插入和删除一个字符的操作变得 和B字符串相等的最少操作数

思路:设A子串为A,很容易可以发现最小操作数=|A|+|B|-2LCS(A,B)。因为插入操作其实是没有意义的,对于最小操作数来说。

这个问题就转换成了求子串和一个串的LCS。

如何求呢?

我们可以用一个nex数组,nex[i][j]表示在第i个字符后出现j字符的位置。这样就可以方便dp了。

定义 dp [ i ][ j ] , 其含义为 —— 和B的前 i 个字符 , 匹配了长度为 j 的 LCS 的最短 A 前缀。

那么有 dp[i][j]=min{dp[i][j],dp[i1][j]}

dp[i][j]=min{dp[i][j],Next[dp[i1][j1]][B[i]]}

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int nex[100010][26],dp[21][26];
char str[100010],pat[30];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int N,M;
        scanf("%s",str+1);
        scanf("%s",pat+1);
        N=strlen(str+1);
        M=strlen(pat+1);
        memset(nex,0x3f,sizeof(nex));
        for(int i=N;i>=1;i--)
        {
            for(int j=0;j<26;j++)
                nex[i-1][j]=nex[i][j];
            nex[i-1][str[i]-'a']=i;
        }
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int L,R;
            scanf("%d%d",&L,&R);
            int ans=0;
            memset(dp,0x3f,sizeof(dp));
            dp[0][0]=L-1;
            for(int i=1;i<=M;i++)
            {
                dp[i][0]=L-1;
                for(int j=1;j<=i;j++)
                {
                    dp[i][j]=min(dp[i][j],dp[i-1][j]);
                    if(dp[i-1][j-1]<R)
                        dp[i][j]=min(dp[i][j],nex[dp[i-1][j-1]][pat[i]-'a']);
                }
            }
            int flag=0;
            for(int i=M;i>=0;i--)
            {
                for(int j=i;j<=M;j++)
                    if(dp[j][i]<=R) 
                    {
                        ans=i;
                        flag=1;
                        break;
                    }
                if(flag==1)
                {
                    break;
                }
            }
            //printf("ans:%d\n",ans);
            printf("%d\n",R-L+1+M-ans*2);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/2462478392Lee/p/13374585.html