[HDOJ4911]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): 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 }
原文地址:https://www.cnblogs.com/kirai/p/4746257.html