求排列的逆序數與輸出前k大的數(分治演算法)

2021-10-03 23:19:47 字數 2678 閱讀 4934

分治把乙個任務分解成多個規模更小的任務,能顯著改善解決問題的效率。歸併排序與快速排序是其典型應用,變形問題有排列的逆序數與輸出前k大的數。

一、排列的逆序數

1.問題簡述

考慮1,2,…,n的排列 i1,i2,…,in,如果其中存在j,k,滿足 j < k 且 ij> ik, 那麼就稱(ij,ik)是這個排列的乙個逆序。乙個排列含有逆序的個數稱為這個排列的逆序數。

現給定1,2,…,n的乙個排列,求它的逆序數。

輸入

第一行是乙個整數n,表示該排列有n個數(n <= 100000)。

第二行是n個不同的正整數,之間以空格隔開,表示該排列。

輸出輸出該排列的逆序數。

樣例輸入

62 6 3 4 5 1

樣例輸出

8注意結果可能超過int的範圍,需要用long long儲存。

2.問題分析

把序列分成前後兩部分,則

整個序列的逆序數=左序列的逆序數+右序列的逆序數+左右間相互形成的逆序數

與歸併排序的思想完全一致,在歸併排序的基礎上新增計數逆序數的功能即可。

3.源**

#include

using

namespace std;

long

long cnt=0;

//注意題目提示

void

mergesort

(int a,

int s,

int e,

int temp)

;//歸併排序

void

merge

(int a,

int s,

int m,

int e,

int tem)

;//合併分別排序後的左右區間

//統計逆序數也在該區間

intmain()

void

mergesort

(int a,

int s,

int e,

int temp)

}void

merge

(int a,

int s,

int m,

int e,

int temp)

}//處理左右部分的剩餘序列

while

(p1<=m)

temp[pt++

]=a[p1++];

while

(p2<=e)

temp[pt++

]=a[p2++];

//放回排序後的序列

for(

int i=

0;i++i)

}

二、輸出前k大的數

1.問題簡述

給定乙個陣列,統計前k大的數並且把這k個數從大到小輸出。

輸入

第一行包含乙個整數n,表示陣列的大小。n < 100000。

第二行包含n個整數,表示陣列的元素,整數之間以乙個空格分開。每個整數的絕對值不超過100000000。

第三行包含乙個整數k。k < n。

輸出從大到小輸出前k大的數,每個數一行。

樣例輸入

104 5 6 9 8 7 1 2 3 0

5樣例輸出98

765

2.問題分析

目標明確,不使用直接排序再輸出的方法,採用分治求解。與快速排序思想一致:先選定某個值k1=a[0],進行一次序列調整後,計算出位於k1及之後的數的個數num(不小於k1的數的個數),如果

(1)num==k,即num個數恰好與所需的k個數一樣多,結束計算;

(2)num>k,意味著k1右側的數多於k個了,需要再次再右側進行序列調整;

(3)num在快排裡,第(2)、(3)步都是需要執行的,而本例中只選擇其中之一執行,且快排中是沒有(1)中的結束條件的。

3.源**

#include

#include

using

namespace std;

void

lagerst_k

(int a,

int s,

int e,

int k)

;//在快速排序的基礎上增加引數 k

intmain()

return0;

}void

lagerst_k

(int a,

int s,

int e,

int k)

//a[i]=k1;

//與快排的區別部分

int num=e-i+1;

if(num==k)

return;if

(numlagerst_k

(a,s,i-

1,k-num);if

(num>k)

lagerst_k

(a,i+

1,e,k)

;}

在體會分治思想的同時,回顧歸併排序與快速排序。

求排列的逆序數

考慮1,2,n n 100000 的排列i1,i2,in,如果其中存在j,k,滿足 j k 且 ij ik,那麼就稱 ij,ik 是這個排列的乙個逆序。乙個排列含有逆序的個數稱為這個排列的逆序數。例如排列 263451 含有8個逆序 2,1 6,3 6,4 6,5 6,1 3,1 4,1 5,1 因...

求排列的逆序數

openjudge011 題目 乙個排列含有逆序的個數稱為這個排列的逆序數。例如排列 263451 含有8個逆序 2,1 6,3 6,4 6,5 6,1 3,1 4,1 5,1 因此該排列的逆序數就是8。顯然,由1,2,n 構成的所有n 個排列中,最小的逆序數是0,對應的排列就是1,2,n 最大的逆...

求排列的逆序數

求排列的逆序數 標題 1020 求排列的逆序數 檢視提交統計提問 總時間限制 1000ms 記憶體限制 65536kb 描述在internet上的搜尋引擎經常需要對資訊進行比較,比如可以通過某個人對一些事物的排名來估計他 或她 對各種不同資訊的興趣,從而實現個性化的服務。對於不同的排名結果可以用逆序...