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;
}
时间: 2024-10-12 22:09:09

Inversion(HDU_4911) 归并排序+逆序数对的相关文章

hdu 4911 Inversion(求逆序数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 528    Accepted Submission(s): 228 Problem Description bobo has a sequence a1,a2,

AcWing:108. 奇数码问题(归并排序 + 逆序数)

你一定玩过八数码游戏,它实际上是在一个3×3的网格中进行的,1个空格和1~8这8个数字恰好不重不漏地分布在这3×3的网格中. 例如: 5 2 8 1 3 _ 4 6 7 在游戏过程中,可以把空格与其上.下.左.右四个方向之一的数字交换(如果存在). 例如在上例中,空格可与左.上.下面的数字交换,分别变成: 5 2 8 5 2 _ 5 2 8 1 _ 3 1 3 8 1 3 7 4 6 7 4 6 7 4 6 _ 奇数码游戏是它的一个扩展,在一个nn×nn的网格中进行,其中nn为奇数,1个空格和1

HDU 1394 Minimum Inversion Number 【逆序数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题目大意:给一个n,然后给出一组0~n-1的序列,求这个序列的逆序数,以及交换之后的逆序数中的最小值.交换规则是: a1, a2, ..., an-1, an (where m = 0 - the initial seqence) a2, a3, ..., an, a1 (where m = 1) a3, a4, ..., an, a1, a2 (where m = 2) ... an, a1

Minimum Inversion Number_最小逆序数

Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of

数据结构 归并排序-逆序数对

逆序对是指数列a[1],a[2],a[3]-中的任意两个数a[i],a[j] (i<j),如果a[i]>a[j],那么我们就说这两个数构成了一个逆序对. 而归并排序的合并两个排列的过程中 会将右边的有序序列的元素依次插入前面的 有序序列 如(3 7 12)   ( 5 6 8) 将5 插入  (3 7 12) 中 因为后面有序 所以 假设   5和左边全部元素构成逆序对  所以有mid+1 而左边序列又有start1 个数比5 小  所以 逆序数就是  mid+1-start1 这样就能大大缩

Frosh Week(HDU_3743)归并排序+逆序数对

Frosh Week Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2772    Accepted Submission(s): 923 Problem Description During Frosh Week, students play various fun games to get to know each other a

HDU 1394 Minimum Inversion Number(逆序数)

题目链接:HDU 1394 Minimum Inversion Number [题意]给你一个1~N的数字组成的初始序列,然后每一次都将第一个数字移到最后,形成新的序列,然后求出这些序列的逆序数中的最小值. [思路]开始可以用任意一种方法(线段树 or 暴力 or 树状数组)计算出初始数列的逆序数sum,这里我比较懒,就直接用的暴力找的sum,对于a[i](0~~n-1),每挪一个,用sum减去挪之前它右边比它小的数的个数(也就是a[i]个),再用sum加上挪之后左边比它大的数的个数(也就是n-

hdu1394 Minimum Inversion Number(最小逆序数)

Minimum Inversion Number Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 1   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description The inversion

归并排序(逆序数问题)详解

微信公众号:bigsai 前言 在排序中,我们可能大部分更熟悉冒泡排序.快排之类.对归并排序可能比较陌生.然而事实上归并排序也是一种稳定的排序,时间复杂度为O(nlogn). 归并排序是基于分治进行归并的,有二路归并和多路归并.我们这里只讲二路归并并且日常用的基本是二路归并.并且归并排序的实现方式有递归形式和非递归形式.要注意其中的区分(思想上没有大的区别,只是划分上会有区分后面会对比). 并且归并排序很重要的一个应用是求序列中的逆序数个数.当然逆序数也可以用树状数组完成,这里就不介绍了. 归并