CF1363F Rotating Substrings 题解
首先很容易发现如果两个字符串的字符集相同,那么一定可以在 $n$ 次操作内使 $s$ 与 $t$ 相等。
考虑保留尽量多的字符不动,那么操作次数就是 $n$ 减去这个最大值。
考虑一个 $s$ 与 $t$ 的公共子序列满足什么条件可以不动。发现 $s$ 中一个不动的字符前面的所有字符不可能移到这个不动的字符后面,所以只需要满足公共子序列中,每一项在 $s$ 中对应的字符前面的字符集包含于在 $t$ 中对应的字符前面的字符集即可。
那么答案就是 $n$ 减去满足上述条件的最长公共子序列的长度,直接 dp 即可,时间复杂度 $O(n^2)$。
参考代码:
#include<bits/stdc++.h>
#define mxn 2003
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
int T,n,r,c[26],p[mxn],f[mxn];
char s[mxn],t[mxn];
signed main(){
scanf("%d",&T);
while(T--){
scanf("%d%s%s",&n,s+1,t+1);
memset(c,0,sizeof(c));
r=1;
rep(i,1,n){
c[t[i]-'a']++;
while(r<=n&&c[s[r]-'a'])c[s[r]-'a']--,r++;
p[i]=r-1;
}
if(p[n]<n){
puts("-1");
continue;
}
rep(i,1,n)f[i]=0;
rep(i,1,n){
drep(j,p[i],1)f[j]=max(f[j],f[j-1]+(t[i]==s[j]));
rep(j,1,n)f[j]=max(f[j],f[j-1]);
}
printf("%d\n",n-f[n]);
}
return 0;
}