考虑这个旋转操作,本质上就是把一个字符往左移动一些位。
如果两个字符串每个字符的数量相等,那么如果从左到右逐一归位必然可以构造出一组解,当然如果数量不同那肯定没法归位。
然后不难发现本质上就是一个匹配问题,我们固定一些 $S$ 中的位置,这些位置必须满足在 $T$ 中的相对顺序和在 $S$ 中一样,只归位剩下的,不难发现必然也是一组解。
相当于我们现在要找一个类似 LCS 的东西。但是会发现它和 LCS 是有差别的直接拿 LCS 不太对。因为当有一个 $S$ 中的位置和 $T$ 中的一个位置 $c$ 不匹配的时候,我们必须保证 $S$ 中这个位置后面必须有一个 $c$ ,然后把 $c$ 挪上来和这个 $T$ 的位置匹配。也就是说,如果 $S$ 中的 $c$ 的个数小于当前 $T$ 中的个数,那么我们不能在这里让 $S$ 中的这个位置失配。
由于这个东西是与后缀的 $c$ 的个数有关的,所以我们考虑设 $dp[i][j]$ 表示当前匹配完了 $S$ 的最后 $i$ 个字符和 $T$ 的最后 $j$ 个字符。然后对于当前 $i$ 中有某个字符出现次数小于 $T$ 中后 $i$ 中某个字符的状态全部整成 $-\infin$。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue" #include "string" #include "unordered_map" #include "assert.h" #include "ctime" using namespace std;#define MAXN 2006 #define rep( i , a , b ) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per( i , a , b ) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all( x ) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll;int n;char s[MAXN] , t[MAXN];int S[MAXN][27 ] , T[MAXN][27 ];int f[MAXN][MAXN];void solve ( ) { cin >> n; scanf ( "%s%s" , s + 1 , t + 1 ); rep ( i , 0 , n + 1 ) rep ( j , 0 , n + 1 ) f[i][j] = -0x3f3f3f3f ; per ( i , n , 1 ) { memcpy ( S[i] , S[i + 1 ] , sizeof S[i + 1 ] ); ++ S[i][s[i] - 'a' ]; memcpy ( T[i] , T[i + 1 ] , sizeof T[i + 1 ] ); ++ T[i][t[i] - 'a' ]; } rep ( i , 0 , 25 ) if ( S[1 ][i] != T[1 ][i] ) return void ( puts ("-1" ) ); f[n + 1 ][n + 1 ] = 0 ; per ( i , n + 1 , 2 ) per ( j , n + 1 , 2 ) { if ( f[i][j] >= 0 ) { if ( s[i - 1 ] == t[j - 1 ] ) f[i - 1 ][j - 1 ] = max ( f[i - 1 ][j - 1 ] , 1 + f[i][j] ); if ( T[j - 1 ][t[j - 1 ] - 'a' ] <= S[i][t[j - 1 ] - 'a' ] ) f[i][j - 1 ] = max ( f[i][j - 1 ] , f[i][j] ); f[i - 1 ][j] = max ( f[i - 1 ][j] , f[i][j] ); } else break ; } int re = -0x3f3f3f3f ; rep ( i , 1 , n ) re = max ( re , f[1 ][i] ); printf ("%d\n" ,n - re); } signed main ( ) { int T; cin >> T; while ( T-- ) solve ( ); }