我們知道,求逆序對最典型的方法就是樹狀陣列,但是還有一種方法就是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。因此,可以在歸併 排
序中的合併過程
中計算逆序數.
題目:
題意:給定乙個序列a,每次只允許交換相鄰兩個數,最少要交換多少次才能把它變成非遞降序列.
#include #include #include using namespace std;
const int n = 1005;
int a[n],tmp[n];
int ans;
void merge(int l,int m,int r)
else
}while(i <= m) tmp[k++] = a[i++];
while(j <= r) tmp[k++] = a[j++];
for(int i=l;i<=r;i++)
a[i] = tmp[i];
}void merge_sort(int l,int r)
}int main()
{ int n,t,tt=1;
scanf("%d",&t);
while(t--)
{scanf("%d",&n);
for(int i=0;i
歸併排序求逆序對
排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...
歸併排序求逆序對
現在給定乙個有n個數的數列ai。若對於i j,有ai aj,則稱 i,j 為數列的乙個逆序對。例如,2,3,8,6,1 有五個逆序對,分別是 1,5 2,5 3,4 3,5 4,5 現在請你求出乙個給定數列的逆序對個數。輸入格式 乙個整數t,表示有多少組測試資料。每組測試資料第一行是乙個正整數n 1...
歸併排序求逆序對
求逆序對方法有兩種 樹狀陣列和歸併排序,還有暴力 暴力就是兩個for迴圈判斷當ia j 則ans 這裡先說歸併排序吧,在另一篇部落格中再講樹狀陣列求逆序對 實際上是我寫樹狀陣列的還有bug沒找到.include include include includeusing namespace std c...