HDU 4944 逆序数对
生活随笔
收集整理的這篇文章主要介紹了
HDU 4944 逆序数对
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4911
題意:
給出一個序列,可以相鄰的交換k次,求 k 次之后,逆序數(shù)對最少是多少;
?
分析:
可以發(fā)現(xiàn),無論怎么交換之后,總共的逆序數(shù)對只會-1,那么結(jié)果就是,將這個序列排整齊時,要兩兩交換的次數(shù)-k;題目就轉(zhuǎn)換為求這個序列的逆序數(shù)對有多少;
這樣的兩兩交換好像是冒泡排序,冒泡排序是O(n^2);
正確解法是歸并排序;當我們合并兩個有序序列時,如果,要將后面的插入到前一個中間,那么這里就有m-i+1個逆序數(shù)對;
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e5 + 5; 6 7 __int64 cnt,k; 8 int a[maxn],c[maxn]; 9 10 11 void merge(int* a,int first,int mid,int last,int* c) { 12 int i = first,j=mid+1; 13 int m = mid,n=last; 14 int k = 0; 15 while(i<=m||j<=n) { 16 if(j>n||(i<=m&&a[i]<=a[j])) { 17 c[k++] = a[i++]; 18 } 19 else { 20 c[k++] = a[j++]; 21 cnt += (m-i+1); 22 } 23 } 24 for(i=0;i<k;i++) 25 a[first+i] = c[i]; 26 } 27 28 void mergeSort(int* a,int first,int last,int* c) { 29 if(first<last) { 30 int mid = (first+last)/2; 31 mergeSort(a,first,mid,c); 32 mergeSort(a,mid+1,last,c); 33 merge(a,first,mid,last,c); 34 } 35 } 36 37 int main() 38 { 39 int n; 40 while(~scanf("%d%I64d",&n,&k)) { 41 for(int i=0;i<n;i++) 42 scanf("%d",&a[i]); 43 memset(c,0,sizeof(c)); 44 cnt = 0; 45 mergeSort(a,0,n-1,c); 46 printf("%lld\n",max(cnt-k,0LL)); 47 } 48 return 0; 49 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/TreeDream/p/6822322.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的HDU 4944 逆序数对的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Aix 6.1下安装Oracle11g详
- 下一篇: 20155225 实验三《敏捷开发与XP