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;
}
posted @ 2024-01-07 12:57  zifanwang  阅读(2)  评论(0编辑  收藏  举报  来源