演算法十 最小交換

2021-08-20 06:40:55 字數 1442 閱讀 8274

問題描述

給定乙個 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,表示排...