http://acm.hdu.edu.cn/showproblem.php?pid=6774
题意:长为n(1e5)的串A,长为m(20)的串B,q组询问,每次问把A中一段区间变成B的最少操作次数(删或增字符)。
思路:计算LCS,然后一算就好了,难点是LCS,设
f
(
i
,
j
,
k
)
f(i,j,k)
f(i,j,k):A前i个,B前j个,LCS为k,对应的A中尽量靠右的第一个元素下标。转移很简单,分当前两个元素同或不同。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+100;
int T,n,m;
int f[maxn][22][22];
char s[maxn],t[22];
int main()
{
//freopen("input.in","r",stdin);
cin>>T;
while(T--)
{
cin>>s+1>>t+1;
n=strlen(s+1);
m=strlen(t+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=1;k<=min(i,j);k++)
{
if(s[i]!=t[j])f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
else {f[i][j][k]=f[i-1][j-1][k-1];if(k==1)f[i][j][k]=i;}
}
}
}
int q,l,r,ans;
cin>>q;
while(q--)
{
scanf("%d%d",&l,&r);
ans=0;
for(int i=m;i>=1;i--)
{
if(f[r][m][i]>=l){ans=i;break;}
}
printf("%d\n",r-l+1-ans+m-ans);
}
}
return 0;
}