标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2744 Accepted Submission(s): 1015
求交换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 }
标签:
原文地址:http://www.cnblogs.com/vincentX/p/4746257.html