POJ 2299 Ultra-QuickSort 树状数组/归并排序 求逆序数

1.为什么最小交换次数是求数组的逆序数?

比如91054    9作为最大,它肯定要沉到最后面,所以肯定要交换4次 并且9的逆序数 (9,1)(9,0)(9,5)(9,4) 正好是4, 同时9沉下去后,其他数字的相对位置没有改变,同样的道理一个数有多少个逆序数就要交换多少次,所以肯定要交换的次数就是最小交换次数就是这些逆序数的和。

2.如何求数组逆序数?

1.归并排序时顺便记录一下逆序数的个数 

void mergesort(int start,int mid,int end){
    int i=start,k=start,j=mid+1;
    while(i<=mid&&j<=end){
        if(a[i]<=a[j])b[k++]=a[i++];
        else{
            ans+=j-k;//注意到如果a[i]>a[j] 此时就是找到一对逆序数,同时此时b[k]==a[i],注意到如果a[i]>a[j],那么a[i+1]>a[i]>a[j],甚至在i~j的区间内都是要大于a[j]所以要加上这些逆序数
            b[k++]=a[j++];
        }
    }
        while(i<=mid)b[k++]=a[i++];
        while(j<=end)b[k++]=a[j++];
        //while(start<=end)a[start++]=b[start];    
        for(int i=start;i<=end;i++)a[i]=b[i];
} 

2.树状数组/线段树

http://blog.youkuaiyun.com/lirui7610/article/details/79586404

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值