題意:給定乙個序列a,每次只允許交換相鄰兩個數,最少要交換多少次才能把它變成非遞降序列.
思路:題目就是要求逆序對數,我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是merge_sort(),即歸併排序。實際上歸併排序的交換次數就是這個陣列的逆序對個數,歸併排序是將數列a[l,h]分成兩半a[l,mid]和a[mid+1,h]分別進行歸併排序,然後再將這兩半合併起來。在合併的過程中(設l<=i<=mid,mid+1<=j<=h),當a[i<=a[j]時,並不產生逆序數;當a[i]>a[j]時,在前半部分中比a[i]大的數都比a[j]大,將a[j]放在a[i]前面的話,逆序數要加上mid+1-i。因此,可以在歸併排序中的合併過程中計算逆序數。
code:
1 #include 2 #include3 #include 4
5using
namespace
std;
6const
int n = 1005;7
8int
a[n],tmp[n];
9int
ans;
1011
void merge(int l,int m,int
r)12
23else
2427}28
while(i <= m) tmp[k++] = a[i++];
29while(j <= r) tmp[k++] = a[j++];
30for(int i=l;i<=r;i++)
31 a[i] =tmp[i];32}
3334
void merge_sort(int l,int
r)3543}
4445
intmain()
4658
return0;
59 }
POJ 重要逆序對
總時間限制 10000ms 單個測試點時間限制 1000ms 記憶體限制 65536kb 描述 給定n個數的序列a1,a2,an,定義乙個數對 ai,aj 為 重要逆序對 的充要條件為 i j 且 ai 2aj。求給定序列中 重要逆序對 的個數。輸入 第一行為序列中數字的個數n 1 n 200000...
poj 2299 求逆序對
題目大意 求逆序對 解題思路 分治法,類似於歸併排序。a 1.n 將原問題劃分為2個子問題a 1.n 2 a n 2 1.n 並且兩個子陣列已經排好序了,1.n 2的逆序對已經求好,n 2 1.n的逆序對也已經求好了 所以求兩個子問題之間的逆序對,在歸併排序的過程中,當a i a j 時,逆序對的數...
樹狀陣列求逆序對 POJ 2299 3067
前幾天開始看樹狀陣列了,然後開始找題來刷。首先是 poj 2299 ultra quicksort 這題是指給你乙個無序序列,只能交換相鄰的兩數使它有序,要你求出交換的次數。實質上就是求逆序對,網上有很多人說它的原理是氣泡排序,可以用歸併排序來求出,但我一時間想不出它是如何和歸併排序搭上邊的 當初排...