牛客网:18后端:字母交换

这篇博客介绍了如何通过动态规划算法解决字符交换问题,以达到将字符串中相同字符相邻的最小交换次数。首先记录每个字符的位置,然后找出规律,如连续字符序列的交换次数。博主提供了代码实现,并在主函数中遍历所有字符,找出最大连续区间,最终输出满足条件的最小交换次数。
摘要由CSDN通过智能技术生成

 

这里读了一篇博客:

牛客-字母交换_南nn的博客-CSDN博客

关键是找到规律然后dp,这是dp吧,好像是的...

首先我们记录每个字符的位置序列到一个vector中

接下来就是规律:

比如这个a.....a这个序列,要把前面那个a移动到与后面那个a相邻,最小的次数是不是下标相减再减1呢?没错就是这样

我们第一步先把同字符移动到相邻需要的步数记录下来,接着更新大的。

然后来考虑一个a...a...a...a的例子,这样把a移动到相邻最少多少步呢?可以想象,中间的已经求出来了,我们只要把两边的a缩到中间就行,那其实是下标相减减1再减去中间相同字符的个数。

这样我们就求出了使某一个字符在一定数量上相邻所花费的最小交换次数,接着选出连续最大的区间,交换次数小于要求的就是我们要的

代码如下所示:

#include <bits/stdc++.h>
using  namespace std;
int m;
string str;
int maxi(vector<int>& x){
    int n=x.size();
    vector<vector<int>> dp(n,vector<int>(n,0));
    for (int i = 0; i < n-1; ++i) {
        dp[i][i+1]=x[i+1]-x[i]+1;
    }
    for (int k = 2; k < n; ++k) {
        for (int i = 0; i < n-k; ++i) {
            int left=i,right=i+k;
            dp[left][right]=dp[left+1][right-1]+(x[right]-x[left]-1)-(right-left-1);
        }
    }
    int res=0;
    for (int i = 0; i < n; ++i) {
        for (int j = i+1; j < n; ++j) {
            if(dp[i][j]<=m&&(j-i+1)>res){
                res=j-i+1;
            }
        }
    }
    return res;
}

int main() {
    cin>>str>>m;
    vector<vector<int>> a(26);
    for (int i = 0; i < str.size(); ++i) {
        a[str[i]-'a'].push_back(i);
    }
    int res=0;
    for (int i = 0; i < 26; ++i) {
        int num=maxi(a[i]);
        if (num>res) res=num;
    }
    cout<<res<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值