洛谷 P1116 車廂重組

2021-10-01 20:03:32 字數 2749 閱讀 6132

題目描述:

在乙個舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。乙個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180

18018

0度,則可以把相鄰兩節車廂的位置交換,用這種方法可以重新排列車廂的順序。於是他就負責用這座橋將進站的車廂按車廂號從小到大排列。他退休後,火車站決定將這一工作自動化,其中一項重要的工作是編乙個程式,輸入初始的車廂順序,計算最少用多少步就能將車廂排序。

輸入格式:

共兩行。第一行是車廂總數n(≤

10000

)n( \le 10000)

n(≤100

00)。第二行是n

nn個不同的數表示初始的車廂順序。

輸出格式:

乙個整數,最少的旋轉次數。

題目的本質是,給定乙個正整數序列,只允許交換相鄰數字的順序,問至少交換多少次,可以將整個序列排好序。這道題本質上是求逆序對個數(逆序對指某兩個數字大數排在小數之前)。而求逆序對個數,有個經典的演算法,也就是歸併排序。**如下:

#

include

using

namespace std;

const

int n =

1e4+10;

int n;

int a[n]

, tmp[n]

;int res =0;

void

merge

(int l,

int mid,

int r)

while

(i <= mid) tmp[idx++

]= a[i++];

while

(j <= r) tmp[idx++

]= a[j++];

for(

int k = l; k <= r; k++

) a[k]

= tmp[k];}

void

merge_sort

(int l,

int r)

intmain()

時間複雜度o(n

log⁡n)

o(n\log n)

o(nlogn)

,空間複雜度o(n

)o(n)

o(n)

,歸併時需要個臨時陣列。

演算法正確性證明:

首先證明最小交換次數r

rr確實等於逆序對總數sss:

由於交換相鄰兩個數,逆序對至多減少1

11個,而逆序對數等於0

00等價於已經由小到大排好序,所以r≥s

r\ge s

r≥s。由氣泡排序的過程知道,我們可以做到每次交換相鄰兩個數,都使得逆序數減少1

11,所以r

rr是可以取到s

ss的。所以r=s

r=sr=

s。其次證明,上述歸併排序的過程,的確算出了逆序對數。先證明每次歸併的時候,res

resre

s都計入了當前被歸併序列的逆序數。設f(x

1,x2

,...

,xn)

f(x_1,x_2,...,x_n)

f(x1​,

x2​,

...,

xn​)

為向量(x1

,x2,

...,

xn

)(x_1,x_2,...,x_n)

(x1​,x

2​,.

..,x

n​)的逆序對總數,容易證明遞推式:f(x

1,x2

,...

,xn)

=f(x

1,..

.,xi

−1)+

f(xi

,...

,xn)

+∣

∣f(x_1,x_2,...,x_n)=f(x_1,...,x_)+f(x_,...,x_n)+\\|\|

f(x1​,

x2​,

...,

xn​)

=f(x

1​,.

..,x

i−1​

)+f(

xi​,

...,

xn​)

+∣∣符號說明:對於集合s

ss,∣s∣

|s|∣s

∣表示s

ss中元素個數。而在每次歸併的時候,右邊前兩項都為0

00,而第三項可以在歸併的時候統計:如果index1指向的數小於等於index2指向的數,那麼沒有產生逆序,否則index1直到mid的數都與index2指向的數產生了逆序對,產生出mid-index1+1個逆序對。每次歸併完成後,所歸併的那一段序列的逆序對全被消滅,說明了所有逆序對的計數都含在了變數res裡。

現在可以證明演算法的正確性了。先證明merge_sort函式將[left,right]之間的數的逆序數計入了res,並將區間內數排好序。對區間內數的數量做歸納。當只有1

11個數的時候,結論正確。假設對1,.

..,n

−1

1,..., n-1

1,...,

n−1結論都正確,當區間內有n

nn個數的時候,由於[left,mid]和[mid+1,right]內個數都嚴格小於n

nn,由歸納假設,對左右兩半邊做merge_sort後,都達到了效果,再加上merge函式計入了分屬兩半邊的數產生的逆序數,就得到了總逆序數。由數學歸納法,所以結論對任何n

nn都成立。正確性也得到了證明。

複雜度證明可以由master定理得到。

洛谷 P1116 車廂重組

在乙個舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。乙個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180180度,則可以把相鄰兩節車廂的位置交換,用這種方法可以重新排列車廂的順序。於是他就負責用這座橋將進站的車廂按車廂號從小到大排列。他退休後,火車站決定將這一工作自動化,其...

洛谷P1116 車廂重組

題目鏈結 題目描述 在乙個舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。乙個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180度,則可以把相鄰兩節車廂的位置交換,用這種方法可以重新排列車廂的順序。於是他就負責用這座橋將進站的車廂按車廂號從小到大排列。他退休後,火車站決定將這一...

P1116 車廂重組

題目描述 在乙個舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。乙個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180180度,則可以把相鄰兩節車廂的位置交換,用這種方法可以重新排列車廂的順序。於是他就負責用這座橋將進站的車廂按車廂號從小到大排列。他退休後,火車站決定將這一工作...