题目链接: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): 2744 Accepted Submission(s): 1015
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次以后所获得的数列的最小的逆序数。
如果逆序数大于0,说明数列中有两个数可以交换,使得逆序数-1。所以所求交换k次所得数列最小逆序数的结果就是排序结束后交换次数-k,这个结果大于等于0。
代码如下:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 100010; 9 int num[maxn]; 10 int Right[maxn], Left[maxn]; 11 LL ans; 12 13 void merge(int* num, int p, int q, int r) { 14 int n1, n2, i, j, k; 15 n1 = q - p + 1; 16 n2 = r - q; 17 for(i = 0; i < n1; i++) { 18 Left[i] = num[p+i]; 19 } 20 for(i = 0; i < n2; i++) { 21 Right[i] = num[q+i+1]; 22 } 23 Left[n1] = Right[n2] = 0x7FFFFFFF; 24 i = 0; 25 j = 0; 26 for(k = p; k <= r; k++) { 27 if(Left[i] <= Right[j]) { 28 num[k] = Left[i]; 29 i++; 30 } 31 else { 32 num[k] = Right[j]; 33 j++; 34 ans += (n1 - i); 35 } 36 } 37 } 38 39 void mergesort(int* num, int p, int r) { 40 int q; 41 if(p < r) { 42 q = (p + r) / 2; 43 mergesort(num, p, q); 44 mergesort(num, q+1, r); 45 merge(num, p, q, r); 46 } 47 } 48 49 int main() { 50 int n, k; 51 while(~scanf("%d %d", &n, &k)) { 52 ans = 0; 53 for(int i = 0; i < n; i++) { 54 scanf("%d", &num[i]); 55 } 56 mergesort(num, 0, n-1); 57 cout << ((ans-k) > LL(0) ? ans-k : 0) << endl; 58 } 59 }