問題描述
給定乙個 1 到 n 的排列(即乙個序列,其中 [1,n] 之間的正整數每個都出現了恰好 1 次)。
你可以花 1 元錢交換兩個相鄰的數。
現在,你希望把它們公升序排序。求你完成這個目標最少需要花費多少元錢。
第一行乙個整數 n,表示排列長度。
接下來一行 n 個用空格隔開的正整數,描述這個排列。
輸出一行乙個非負整數,表示完成目標最少需要花多少元錢。
3 (排列長度)
3 2 1
3
你可以:
花 1 元交換 1,2,序列變成 3 1 2。
花 1 元交換 1,3,序列變成 1 3 2。
花 1 元交換 2,3,序列變成 1 2 3。
總共需要花 3 元。
可以證明不存在更優的解。
[每次交換相鄰的兩個數都會使逆序對 +1 或 -1。]
[逆序對數目不為零時,一定存在相鄰的逆序對。]
[因此最優策略顯然是每次都讓逆序對數目 -1。]
[所以答案即為逆序對數目
。] [樸素的演算法時間複雜度是 o(n^2) 的。]
[用歸併排序求逆序對數
可以通過本題。需要提醒的是,答案可能超過 32 位整數的範圍哦。]
[逆序對數目同樣可以用樹狀陣列優化樸素的 o(n^2) 演算法,並獲得和歸併排序相同的時間複雜度。]
// ***************== **實現開始 ***************==
//seq:原序列,為了方便處理,將其設為全域性變數
//seqtemp:用以輔助計算的臨時陣列
//cnt:統計逆序對個數
vectorseq,seqtemp;
long long cnt;
//歸併排序
//l,r分別為歸併排序排序區間的左右端點
void mergesort(int l,int r)
}for(int i = l; i <= r; ++i)
seq[i] = seqtemp[i];//將排序後的序列複製回原序列的對應位置
}// 這個函式的功能是計算答案(即最少花費的金錢)
// n:表示序列長度
// a:儲存整個序列 a
// 返回值:最少花費的金錢(需要注意,返回值的型別為 64 位有符號整數)
long long getanswer(int n, vectora)
// ***************== **實現結束 ***************==
演算法 最小交換次數
給出乙個具有n個不同值的陣列a,找出將陣列排序成順序所需的最小交換次數。陣列a 1 4 6 3 7 9 5 2 1.隨機生成小於n的序列,使用乙個陣列標記當前生成的數字是否已經在序列中,值為1表示已經存在 2.按位比較替換,直到當前位的值是終態序列對應位上的值。include include inc...
交換最大最小值
7 2 交換最小值和最大值 15 分 本題要求編寫程式,先將輸入的一系列整數中的最小值與第乙個數交換,然後將最大值與最後乙個數交換,最後輸出交換後的序列。注意 題目保證最大和最小值都是唯一的。輸入在第一行中給出乙個正整數n 10 第二行給出n個整數,數字間以空格分隔。在一行中順序輸出交換後的序列,每...
鄧俊輝演算法訓練營習題 最小交換
最小交換 時間限制 1 sec 空間限制 256 mb 問題描述 給定乙個 1 到 n 的排列 即乙個序列,其中 1,n 之間的正整數每個都出現了恰好 1 次 你可以花 1 元錢交換兩個相鄰的數。現在,你希望把它們公升序排序。求你完成這個目標最少需要花費多少元錢。輸入格式 第一行乙個整數 n,表示排...