题解 | #冒泡排序#

冒泡排序

https://www.nowcoder.com/practice/6a33f0ce1e1649069f222e69e1d3d05f

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const int N = 51;
//dp[i][k] 表示数组a[0,i] 执行了不超过k次特定操作后 最大减少的逆序数对 的数量。 答案= a[0,n-1]总逆序数对个数 - dp[n-1][k]
int dp[N][N];
int n,k;
vector<int> a(N, 0);
// 求数组t 在范围[l,r]上的逆序数对 个数
int getCnt(vector<int> t, int l, int r, bool isReverse){
    int res = 0;
    if(isReverse){
        reverse(t.begin()+l, t.begin()+r+1);
    }
    for(int i = l; i <= r; i++){
        for(int j = i + 1; j <= r; j++){
            if(t[i]>t[j]) res++;
        }
    }
    return res;
}
int main() {
    int n,k;
    cin >> n >> k;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }

    for(int i = 1; i < n; i++){
        for(int k_ = 1; k_ <= k; k_++){
            int tmp = -1;
            //枚举范围[t,i]
            for(int t = 0; t < i; t++){
                //不翻转 和 翻转的 逆序数对的差距
                int d = getCnt(a, t, i, false) - getCnt(a, t, i, true);
                if(d < 0) d = 0;
                tmp = max(tmp, dp[t-1][k_-1]+d);
            }
            // tmp是数组每个范围上,特定操作不超过k的 最大逆序数对 减少数
            dp[i][k_] = max(dp[i-1][k_], tmp);
        }
    }
    cout << getCnt(a, 0,n-1, false) - dp[n-1][k] << endl;
    return 0;

}
// 64 位输出请用 printf("%lld")

#每日一题#
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-02 17:28
25届每天都在焦虑找工作的事情0offer情绪一直很低落硬撑着面了一个岗位岗位有应酬的成分面试的时候hr给我出各种场景题问的问题比较犀利&nbsp;有点压力面的感觉感觉有点回答不上来本来就压抑的情绪瞬间爆发了呢一瞬间特别想哭觉得自己特别没用没绷住掉眼泪了事后想想觉得自己挺有病的&nbsp;真的破大防了
喜欢唱跳rap小刺猬...:我觉得没关系吧,之前有一次面试leader给我压力面,我顶住了压力,结果入职的时候发现组里氛围很差,果断跑路。其实从面试就能大概看出组的情况,面试体验好的组倒是不一定好,但是面试体验不好的组。。。就很难说
点赞 评论 收藏
分享
自学java狠狠赚一...:骗你点star的,港卵公司,记得把star收回去
点赞 评论 收藏
分享
king122:专业技能不要写这么多,熟悉和熟练你经不住问,排版有些难看,中间的空隙搞小一点,项目描述的话感觉是从课程中抄下来的,改一改吧,不然烂大街了,每个项目都写一两点,用什么技术实现了什么难点,然后再写一些数字上去像时间又花了90%这样,这样面试会多一些,如果觉得自己的项目还是不够用的话,我有几个大厂最近做过的实习项目,感兴趣的话可以看我简介中的项目地址
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务