poj 2299,題目鏈結
給出長度為n
的序列,每次只能交換相鄰的兩個元素,問至少要交換幾次才使得該序列為遞增序列。
其實就是求逆序數,那麼直接向到的就是冒泡了,交換一次,記錄一次即可。但是n
的範圍達到
50w,冒泡
o(n^2)
的複雜度鐵定超時。
然後、、、發現曾經微軟有一道筆試題類似就是求逆序數的,對,沒錯,用歸併。
例:合併兩個序列(1,3,5
)(2,4,6
),新序列第二個元素是
2,那麼它和它前面的3、
5形成了逆序數對,所以
....
//3880k 391ms
#include #include int buf[500000];
int ret[500000];
unsigned long long count;
void mergearray(int *a, int first, int mid, int last, int *ret)
else
} while(i<=m) ret[k++] = a[i++];
while(j<=n) ret[k++] = a[j++];
for (int i=0;i}void mergesort(int data, int first, int end, int *ret)
}int main()
return 0;
}
POJ 2299 歸併排序
img 分析 統計給定序列中的逆序數,蠻力法複雜度達o n 2 會超時,由於歸併排序複雜度為o nlogn 並且,在排序過程中可以順便統計逆序數,所以用歸併排序可以求出。注意 在求逆序數時要注意,每當前半部分的數被加入到輔助陣列中時,逆序數總數應當增加後半部分已經被新增到輔助陣列中的元素的總個數.i...
poj 2299 逆序數 歸併排序
陷阱啊!一開始我用氣泡排序 bubble sort 來統計。暈,tle。each case 50w.而一趟氣泡排序需要進行的是n 1,n 2,2,1,0的和次比較。即n n 1 2次。總的時間複雜度為o n 2 肯定是吃不消的。於是,可以用歸併排序來求它的逆序數,逆序即為它總共需要變換的次數。這樣時...
poj2299 歸併排序求逆序數
poj2299 逆序數 逆序數就是你如果只能交換臨近的兩個數,那麼將乙個序列變為有序序列所需要的最少交換次數 穩定的排序演算法按理來說都可以求,但通常使用歸併排序可以求逆序數,因為它的時間效率還是很高的,之所以遜於快排,還是因為它對空間的占用稍多,而且用到了迭代吧 提到逆序數我都第乙個想到歸併。思路...