利用归并求逆序数 Inversion

来源:互联网 发布:seo吧 编辑:程序博客网 时间:2024/06/04 11:20

【题目来源】杭电 多校

【题目含义】 给你一个长度为n的序列,你可以交换任意两个相邻的元素来改变该序列的逆序数,你最多可以交换k次,求交换之后序列的最小逆序数。

【题目分析】该题目可以用冒泡排序来模拟序列元素之间的交换,但是O(n^2)的时间复杂度会使你的程序超时,我们可以采用归并排序来减少时间复杂度。

【代码】

#include<iostream>#include<cstdio>using namespace std;const int inf=1<<30;int arr[100005];long long ans;void gbsort(int *arr,int top,int end){    if(top<end-1) {        int mid=(top+end)/2;        gbsort(arr,top,mid);        gbsort(arr,mid,end);        int *left=new int[mid-top+1];        int *right=new int [end-mid+1];        for(int i=top,j=0; i<mid; i++,j++)            left[j]=arr[i];        for(int i=mid,j=0; i<end; i++,j++)            right[j]=arr[i];        left[mid-top]=inf;        right[end-mid]=inf;        for(int k=top,i=0,j=0; k<end; k++) {            if(left[i]<=right[j])                arr[k]=left[i++];             else {                arr[k]=right[j];                ans += mid +j-k;                j++;            }        }        delete []left;        delete []right;    }}int main() {//    freopen("in.txt","r",stdin);    int n,k;    while(scanf("%d%d",&n,&k)!=EOF) {        ans=0;        for(int i=0; i<n; i++) {            scanf("%d",&arr[i]);        }        gbsort(arr,0,n);        cout<<max(ans-k,0LL)<<endl;    }    return 0;}


0 0
原创粉丝点击