1. 程式人生 > 實用技巧 >2020杭電多校(二) String Distance(dp)

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