2020杭电多校(二) String Distance(dp)

本题询问字符串的编辑距离。

观察题目可得,插入操作是没有用的,所有插入操作都能用删除操作,并且至少不会大于。

因此我们发现,对于两个字符串使得他们相等,最小的其实就是保留lcs。

现在询问的数量很多,因此肯定考虑预处理,对于s串l-r,如果能匹配t串,那么我们需要找的是两个串最大能满足条件的lcs。

所谓满足条件可以定义为lcs的最晚出现时间大于l。

因此我们定义状态为f[i][j][k],表示s的前i个与t的前j个的lcs长度为k的最晚出现时间。

我们只需要按照lcs的dp状态多枚举一维就能预处理

对于询问,只需要枚举k即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int mod=998244353;
int f[N][21][21];
string s,t;
int main(){
    ios::sync_with_stdio(false);
    int d;
    cin>>d;
    while(d--){
        int n;
        int i;
        cin>>s>>t;
        n=s.size();
        int m=t.size();
        s=" "+s;
        t=" "+t;
        for(i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                for(int k=1;k<=m;k++){
                    f[i][j][k]=0;
                    if(s[i]==t[j]){
                        if(k==1){
                            f[i][j][k]=i;//初始化
                        }
                        else{
                            f[i][j][k]=f[i-1][j-1][k-1];
                        }
                    }
                    f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);
                    f[i][j][k]=max(f[i][j][k],f[i][j-1][k]);
                }
            }
        }
        int q;
        cin>>q;
        while(q--){
            int l,r;
            cin>>l>>r;
            int j;
            int ans=0;
            for(i=1;i<=m;i++){
                for(j=1;j<=m;j++){
                    if(f[r][j][i]>=l){
                        ans=i;
                        break;
                    }
                }
            }
            cout<<m+r-l+1-2*ans<<endl;
        }
    }
    return 0;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13372939.html