1. 程式人生 > >Inversion(HDU_4911) 歸併排序+逆序數對

Inversion(HDU_4911) 歸併排序+逆序數對

Inversion

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


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 1 2 2 1 3 0 2 2 1
Sample Output 1 2 題目大意:給出一組數字序列,求在最多進行k次相鄰數調換後,有多少逆序數對; 解題思路:用歸併排序求出原序列的逆序數對cnt,再求max(cnt - k, 0 ),即為答案;
#include"iostream"
#include"cstdio"
#include"cstring"
using namespace std;

int a[100005];
int b[100005];	//輔助陣列 
long long cnt;

void Merge(int a[],int p,int q,int r, int b[]){ 
	int s = p, t = q + 1, k = p;
	while(s <= q && t <= r){
		if(a[s] <= a[t]){
			b[k ++] = a[s ++];
		}else{
			b[k ++] = a[t ++];
			cnt += (q - s + 1); // 在原序列a[s...q] > a[t],故有逆序數對 (q-s+1) 個 
		}
	}
	if(s == q + 1)
		for(;t <= r;t ++) b[k ++] = a[t];
	else
		for(;s <= q;s ++) b[k ++] = a[s];
	for(int i = p;i < k;i ++)
		a[i] = b[i];
}

void BottomUpSort(int a[],int first,int last,int b[]){
	if(first < last){
		int mid = (first + last) / 2;
		BottomUpSort(a, first, mid, b);
		BottomUpSort(a, mid + 1, last, b);
		Merge(a, first, mid, last, b);
	}
}

int main(){
	int n, k;
	while(scanf("%d%d",&n,&k) != EOF){
		cnt = 0;
		for(int i = 1;i <= n;i ++)
			scanf("%d",&a[i]);
		BottomUpSort(a,1,n, b);
		cnt = (cnt - k) > 0 ? (cnt - k) : 0;
		//for(int i = 1;i <= n;i ++) printf("%d ",a[i]);
		printf("\n");
		printf("%I64d\n",cnt);
	}
	return 0;
}