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