Codeforces 1363 F. Rotating Substrings —— 循环移位的lcs

202 篇文章 6 订阅

This way

题意:

现在有一个s串,每次可以找一个子串向右循环移位1格,问你变成t串最少需要几步

题解:

从左往右做的话,很明显每次最多只需要移一次即可,那么我们需要找到最多的位置使得它不用移动,那么这看起来是个lcs,但是有两个限制:
首先s只能往左移,那么也就是说在做lcs的时候,只能找比s当前枚举到的位置大的地方进行匹配。
还有就是t串的当前位置已有的26个字母数量每个都需要>=s串,否则的话,还需要从后面去找,此时不能进行转移。

#include<bits/stdc++.h>
using namespace std;
const int N=2e3+5;
char s[N],t[N];
int dp[N][N],num[2][26][N];
int main()
{
    int tim;
    scanf("%d",&tim);
    while(tim--){
        int n;
        scanf("%d%s%s",&n,s+1,t+1);
        memset(num,0,sizeof(num));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<26;j++)
                for(int k=0;k<=1;k++)
                    num[k][j][i]=num[k][j][i-1];
            num[0][s[i]-'a'][i]++;
            num[1][t[i]-'a'][i]++;
        }
            
        int ans=0;
        for(int i=0;i<26;i++){
            if(num[0][i][n]!=num[1][i][n]){
                ans=-1;
                break;
            }
        }
        if(ans==-1){
            printf("-1\n");
            continue;
        }
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j++){
                dp[i][j]=dp[i-1][j-1];
                int f=0;
                for(int k=0;k<26;k++)
                    if(num[0][k][i]>num[1][k][j])
                        f=1;
                if(s[i]==t[j]&&!f)
                    dp[i][j]=dp[i-1][j-1]+1;
                dp[i][j]=max(dp[i-1][j],max(dp[i][j],dp[i][j-1]));
            }
        }
        printf("%d\n",n-dp[n][n]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值