HDU 4911 Inversion

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40032278/article/details/81534668

http://acm.hdu.edu.cn/showproblem.php?pid=4911

题目

一个序列 可以交换任意相邻的两个元素 ,最多可以进行n次,问 最后 最少有多少个逆序对

题解

  1. 显然 答案为 max(cnt - k,0) cnt 表示原来有多少个逆序对
  2. 所以用归并排序计算一下cnt就可以了
#include<bits/stdc++.h>
using namespace std;// cnt-k,0
int a[100010],le[100010],ri[100010];
long long s;
void work(int l,int mid,int r,int a[])
{
    int i,j,k,x,y;
    x=mid-l+1;
    y=r-mid;
    for(i=0; i<x; i++) le[i]=a[l+i];
    for(i=0; i<y; i++) ri[i]=a[mid+i+1];
    le[x]=ri[y]=0x7fffffff;
    i=0;
    j=0;
    for(k=l; k<=r; k++)
    {
        if(le[i]<=ri[j])
        {
            a[k]=le[i];
            i++;
        }
        else
        {
            a[k]=ri[j];
            j++;
            s=s+x-i;
        }
    }
}
int sol(int l,int r,int a[])
{
    if(l<r)
    {
        int mid=(l+r)/2;
        sol(l,mid,a);
        sol(mid+1,r,a);
        work(l,mid,r,a);
    }
}
int main()
{
    int i,n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        s=0;
        sol(0,n-1,a);
        printf("%lld\n",max(s-k,0ll));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40032278/article/details/81534668