日更 2019.6.29 逆序对问题

今儿打开51nod
玩了一下
啥都不会
只会写A+B

复习一下归并排序

#include<bits/stdc++.h>
using namespace std;
void merge(int a[],int l1,int r1,int l2,int r2){
	int i=l1,j=l2,temp[100],index=0;
	while(i<=r1&&j<=r2){
		if(a[i]<a[j]){
			temp[index++]=a[i++];
		}else {
			temp[index++]=a[j++];
		}
	}
	while(i<=r1)temp[index++]=a[i++];
	while(j<=r2)temp[index++]=a[j++];
	for(i=0;i<index;i++){
		a[i+l1]=temp[i];
	}
}
void mergesort(int a[],int l,int r){
	if(l!=r){
		int mid=(l+r)/2;
		mergesort(a,l,mid);
		mergesort(a,mid+1,r);
		merge(a,l,mid,mid+1,r);
	}
}
int main(){
	int n,a[100];
	cin>>n; 
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	for(int i=0;i<n;i++){
		cout<<a[i];
	}
	return 0;
}

归并排序可以上升到逆序对的问题

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

这个题目可以用暴力O(n2)算法,动态规划O(nlogn)

#include<bits/stdc++.h>
using namespace std;
const int N = 500000;

int swap_space[N];//归并排序的交换空间
long long total;//逆序数
void merge(int a[], int begin, int mid,int end){
	int i = begin;
	int j = mid + 1;
	int k = begin;
	while(i <= mid && j <= end){
		if(a[i] < a[j]){
			swap_space[k++] = a[i++];
		}else{
			swap_space[k++] = a[j++];
			total += (mid - i + 1);//total is the reverse count
		}
	}
 
	while(i <= mid)
		swap_space[k++] = a[i++];
	while(j <= end)
		swap_space[k++] = a[j++];
 
	for(i = begin; i <= end; i++){
		a[i] = swap_space[i];
	}
}
 
void mergeSort(int a[], int begin, int end){
	if(begin != end){
		int mid = (begin + end) / 2;
		mergeSort(a,begin, mid);
		mergeSort(a,mid+1, end);
		merge(a,begin,mid,end);
	}
}
int main(){
	int n,a[N];
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	mergeSort(a,0,n-1);
	cout<<total;
	return 0;
}

那么为什么可以用归并来计算逆序对呢?

首先 两个组别的数组之间的元素交换不影响答案,所以在交换过程中累加答案。
其次,两个组别的元素满足这样的关系
a={a1,a2,…},b={b1,b2,…}并且在原数组中满足c={a1,a2,…,b1,b2,…}的顺序
如果a[i]>b[j],则ans+=len(a)-i

eg. a={4,3},b={2,1},c={4,3,2,1}
那么首先对a,b排序
a又变成两个数组
然后排序
于是答案+1
同理b排序,答案+1

于是乎此时a={3,4},b={1,2},c={3,4,1,2}
在应用上面的公式归并排序一遍
答案+2+2

于是答案为6

解答完毕

发布了61 篇原创文章 · 获赞 8 · 访问量 2480

猜你喜欢

转载自blog.csdn.net/weixin_43982216/article/details/94173484