hdu 4911 Inversion ( 2014 Multi-University Training Contest 5)

来源:互联网 发布:小粉红 知乎 编辑:程序博客网 时间:2024/05/18 20:13

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1451    Accepted Submission(s): 591


Problem Description
bobo has a sequence a1,a2,…,an. He is allowed to swap two adjacent numbers for no more than k times.

Find the minimum number of inversions after his swaps.

Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.
 

Input
The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
 

Output
For each tests:

A single integer denotes the minimum number of inversions.
 

Sample Input
3 12 2 13 02 2 1
 

Sample Output
12
 
题解:
       根据定理,存在每次相邻的两个数交换,使逆序数减一,用归并排序求出逆序数再减交换次数即可。

代码:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int maxn=100100;const int maxint= 999999999;int a[maxn];int lef[maxn];int righ[maxn];int n;long long ans;void sort(int l,int temp,int r){    int n1=temp-l+1;    int n2=r-temp;    for(int i=0;i<n1;i++)    lef[i]=a[i+l];    for(int i=0;i<n2;i++)    righ[i]=a[temp+i+1];    lef[n1]=righ[n2]=maxint;    int i=0;    int j=0;    for(int k=l;k<=r;k++)    {        if(lef[i]<=righ[j])        {            a[k]=lef[i];            i++;        }        else        {            a[k]=righ[j];            j++;            ans+=n1-i;//计算逆序数,在lef数组中有n1-i个比righ[j]大的        }    }    return;}void memsort(int l,int r){    int temp=(l+r)/2;    if(l<r)    {    memsort(l,temp);    memsort(temp+1,r);    sort(l,temp,r);    }    return;}int main(){    int k;    while(~scanf("%d%d",&n,&k))    {        ans=0;        for(int i=0;i<n;i++)        {            scanf("%d",&a[i]);        }        memsort(0,n-1);//归并排序        if(ans-k<0)        ans=k;        printf("%I64d\n",ans-k);    }    return 0;}


0 0
原创粉丝点击