博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
归并排序求逆序对
阅读量:5265 次
发布时间:2019-06-14

本文共 1471 字,大约阅读时间需要 4 分钟。

我们知道,求逆序对最典型的方法就是树状数组,但是还有一种方法就是Merge_sort(),即归并排序。

实际上归并排序的交换次数就是这个数组的逆序对个数,为什么呢?

 

我们可以这样考虑:

归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。

在合并的过程中(设l<=i<=mid,mid+1<=j<=h),当a[i]<=a[j]时,并不产生逆序数;当a[i]>a[j]时,在

前半部分中比a[i]大的数都比a[j]大,将a[j]放在a[i]前面的话,逆序数要加上mid+1-i。因此,可以在归并

排序中的合并过程中计算逆序数.

 

题目:

题意:给定一个序列a[],每次只允许交换相邻两个数,最少要交换多少次才能把它变成非递降序列.

1 #include 
2 #include
3 #include
4 5 using namespace std; 6 const int N = 1005; 7 8 int a[N],tmp[N]; 9 int ans;10 11 void Merge(int l,int m,int r)12 {13 int i = l;14 int j = m + 1;15 int k = l; //特别注意,k是从l(字母)开始而不是0;16 while(i <= m && j <= r)17 {18 if(a[i] > a[j])19 {20 tmp[k++] = a[j++];21 ans += m - i + 1;22 }23 else24 {25 tmp[k++] = a[i++];26 }27 }28 while(i <= m) tmp[k++] = a[i++];29 while(j <= r) tmp[k++] = a[j++];30 for(int i=l;i<=r;i++) //一定记得一次归并完成后要把tmp的元素复制给a31 a[i] = tmp[i];32 }33 34 void Merge_sort(int l,int r)35 {36 if(l < r)37 {38 int m = (l + r) >> 1;39 Merge_sort(l,m);40 Merge_sort(m+1,r);41 Merge(l,m,r);42 }43 }44 45 int main()46 {47 int n,T,tt=1;48 scanf("%d",&T);49 while(T--)50 {51 scanf("%d",&n);52 for(int i=0;i

转自:http://blog.csdn.net/acdreamers/article/details/16849761

转载于:https://www.cnblogs.com/qyy-goodluck/p/4391697.html

你可能感兴趣的文章
SQL (FMDB)
查看>>
2012暑期川西旅游之总结
查看>>
Linux发行版的排行
查看>>
宾得镜头大全与发展史
查看>>
spread+wackamole打造全新高可用+负载均衡
查看>>
Xcode 快捷键及代码格式化
查看>>
12010 解密QQ号(队列)
查看>>
Docker简明教程(以安装wget程序为例)
查看>>
2014年辛星完全解读Javascript第一节
查看>>
装配SpringBean(一)--依赖注入
查看>>
daydayup2 codeforces143C
查看>>
ANT打包J2EE项目war包
查看>>
UESTC-我要长高 DP优化
查看>>
java选择文件时提供图像缩略图[转]
查看>>
ubuntu如何安装虚拟机的工具条
查看>>
printf格式输出知识整理
查看>>
sed 命令用法
查看>>
当DIV内出现滚动条,fixed实效怎么办?
查看>>
方维分享系统二次开发, 给评论、主题、回复、活动 加审核的功能
查看>>
Matlab parfor-loop并行运算
查看>>