归并排序找逆序数

题意:
    bobo has a sequence a 1,a 2,…,a n. 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 a i>a j.
 

Input

The input consists of several tests. For each tests: 
The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).
 

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要注意,就是可以交换相邻数字的位置,使得逆序数最小,那么我们肯定是把最小的数字往前换,这样我们算逆序数就只要把原来的逆序数算出来再减去可以交换的次数就好了,当然如果算出来是负数我们就让它直接等于零吧!
 
代码:
 1 #include<iostream>
 2 using namespace std;
 3 const int maxn =100000+5;
 4 const int Q = 50000 + 5;
 5 int arr[maxn];
 6 int lef[Q], rig[Q];
 7 long long  ans;
 8 int lef_size;
 9 int rig_size;
10 void Merger(int arr[], int L, int M, int R)
11 {                                                     //归并整个数组
12     int i, j, k;
13     lef_size = M - L;
14     rig_size = R - M;
15     for (i = L; i < M; i++)
16     {
17         lef[i - L] = arr[i];                          //放在左边的数组
18     }
19     for (i = M; i < R; i++)
20     {
21         rig[i - M] = arr[i];                            //放在右边的数组
22     }
23     i = 0; j = 0; k = L;
24     while (i < lef_size&&j < rig_size)
25     {
26         if (lef[i] <= rig[j])                         //左边数组小于右边数组
27         { 
28             arr[k] = lef[i];                           //把左边数组的数放进整合数组中
29             i++;                                      //左数组下标加加
30             k++;                                      //整合数组下标加加
31             ans += j;                                  //逆序数加加(相当于在找i与下一个i之间插进去的数字,只要有数字插队,就表示
32                                                         //左边(也可以说前面)大于了右边的数字(后面),所以加J,可能有点不好理解,
33                                                            //自行脑补吧!)
34         }
35         else
36         {
37             arr[k] = rig[j];
38             j++;
39             k++;
40         }
41     }
42     while (i < lef_size)
43     {                                             //没有放完的左边的数
44 
45         arr[k] = lef[i];
46         i++;
47         k++;
48         ans += j;
49 
50 
51     }
52     while (j < rig_size)
53     {
54         arr[k] = rig[j];
55         j++;
56         k++;
57 
58     }
59 }
60 void Mergersort(int arr[], int L, int R)
61 {
62     if (L + 1<R)                           //归并排序
63     {
64         int M = (L + R) / 2;
65         Mergersort(arr, L, M);           
66         Mergersort(arr, M, R);
67         Merger(arr, L, M, R);
68     }
69 }
70 int main()
71 {
72     int n;
73     long long k;
74     while (cin >> n>>k)
75     {
76         ans = 0;
77         for (int m = 0; m < n; m++)
78             cin >> arr[m];
79         Mergersort(arr, 0, n);
80         if (ans - k > 0)
81             cout << ans - k << endl;               
82         else
83             cout << "0" << endl;
84     }
85     return 0;
86 }
 
 
 
原文地址:https://www.cnblogs.com/Lynn0814/p/4711816.html