統計逆序對問題遞迴求解

2021-09-23 01:53:24 字數 1237 閱讀 3227

description

設a[0…n-1]是乙個包含n個數的陣列,若在ia[j],則稱(i, j)為a陣列的乙個逆序對(inversion)。

比如 <2,3,8,6,1> 有5個逆序對。請採用類似「合併排序演算法」的分治思路以o(nlogn)的效率來實現逆序對的統計。

乙個n個元素序列的逆序對個數由三部分構成:

(1)它的左半部分逆序對的個數,(2)加上右半部分逆序對的個數,(3)再加上左半部分元素大於右半部分元素的數量。

其中前兩部分(1)和(2)由遞迴來實現。要保證演算法最後效率o(nlogn),第三部分(3)應該如何實現?

此題請勿採用o(n^2)的簡單列舉演算法來實現。

並思考如下問題:

(1)怎樣的陣列含有最多的逆序對?最多的又是多少個呢?

(2)插入排序的執行時間和陣列中逆序對的個數有關係嗎?什麼關係?

輸入格式

第一行:n,表示接下來要輸入n個元素,n不超過10000。

第二行:n個元素序列。

輸出格式

逆序對的個數。

輸入樣例

52 3 8 6 1

輸出樣例

5

#include#include#include#include#includeusing namespace std;

int a[10000];

int merge_inversion(int a, int low, int mid, int high)

else

}if (i <= mid)

else if (j <= high)

for (int k = 0; k < high - low + 1; k ++) a[low + k] = tmp[k];

//for (int i = 0; i < high - low + 1; i ++) printf("%d ", tmp[i]);

//printf("%d %d %d %d\n",low, mid, high, cnt);

return cnt;

}int count_inversion(int a, int low, int high)

return cnt;

}int main ()

int ans = count_inversion(a, 0, n - 1);

printf("%d", ans);

return 0;

}

逆序對問題

逆序對問題。給一列數a1 a2,an 求它的逆序對數,即有多少個有序對 i j 使得 i j 但ai aj n 可以高達106 由於 n 的數量級到了106 所以採用o n2 及以上的時間複雜度肯定會超時,所以必須選取o nlog 2n 及以下時間複雜度的演算法。逆序對的求解思路和歸併排序很像,嘗試...

逆序對的遞迴求法

int cnt 0 逆序對個數 int a 100002 c 100002 void mergesort int l,int r r 右邊界索引 1 else c tmp a i if j includeusing namespace std 歸併求逆序對數,arr 儲存最終有序結果 在函式外申請乙...

遞迴求逆序對個數

給定輸入n,之後輸入1到n的乙個排列,求排列中的逆序對的個數 思路一 思路二 思路二 實現 include include include using namespace std 歸併,並計算出逆序數的個數 intmerge int a,int s,int mid,int e,int b else ...