1.確定初始和目標狀態。
明確。目標狀態的排序狀態。
2.得出置換群,。比如,數字是8 4 5 3 2 7
,目標狀態是
2 3 4 5 7 8
。能寫為兩個迴圈:
(8 2 7)(4 3 5)
。3.觀察當中乙個迴圈,明顯地。
要使交換代價最小,應該用迴圈裡面最小的數字2
。去與另外的兩個數字。7與
8交換。
這樣交換的代價是:
sum - min + (len - 1) * min
化簡後為:
sum + (len - 2) * min
當中,sum
為這個迴圈全部數字的和,
len為長度,
min為這個環裡面最小的數字。
4.考慮到第二種情況,
我們能夠從別的迴圈裡面調乙個數字,進入這個迴圈之中。使交換代價更小。比如初始狀態:1 8 9 7 6
可分解為兩個迴圈:(1)(8 6 9 7)
,明顯。第二個迴圈為
(8 6 9 7)
,最小的數字為6。
我們能夠抽調整個數列最小的數字1
進入這個迴圈。使第二個迴圈變為:
(8 1 9 7)
。 讓這個1
完畢任務後,再和
6交換。讓
6又一次回到迴圈之後。
這樣做的代價明顯是:
sum + min + (len + 1) * smallest
當中,sum
為這個迴圈全部數字的和。
len為長度,
min為這個環裡面最小的數字,
smallest
是整個數列最小的數字。
5.因此,對乙個迴圈的排序,其代價是
sum - min + (len - 1) * min
和sum + min + (len + 1) * smallest
之中小的那個數字。但這裡兩個公式還不知道怎麼推出來的。
6.我們在計算迴圈的時候,不須要記錄這個迴圈的全部元素,僅僅須要記錄這個迴圈的最小的數及其和。
7.在儲存數目的時候,我們能夠
使用乙個hash
結構。將元素及其位置相應起來,以達到知道元素,能夠高速反查元素位置的目的。
這樣就不必要乙個個去搜尋。
#include#include#includeusing namespace std;
const int maxn = 10010;
int a[maxn],b[maxn],dir[100005];
int vis[maxn];
int main()
sort(b,b+n);
memset(vis,0,sizeof(vis));
int ans = 0;
for(int i = 0; i < n; i++)
///求出在當前這個迴圈中的最小花費;
int tmp = min(min_*(len-1) + sum-min_, b[0]*(len+1) + sum + min_);
ans += tmp;}}
printf("%d\n",ans);
}return 0;
}
poj 3270 Cow Sorting 置換問題
有n頭牛,沒頭牛都有自己的暴躁指數,並且互補相同,要把這些牛按暴躁指數從小到大排列,每次交換兩頭牛,消耗的體力為兩頭牛的暴躁指數和。應用的知識為置換。如把 1 2 3 4 5 6 變成 6 3 4 2 1 5 發現可以分成兩組來交換,第一組是 6 1 5 第二組為 2,3,4 只需交換組內的元素就可...
更換ubuntu預設使用核心
在之前的文章中,有寫如何更換核心。在linux開機的時候,會預設使用更高版本的核心。那麼如何更改預設啟動的核心呢?在linux開機時按 shift 進入grub選單,然後選擇ubuntu高階選項,裡面會有核心版本。記下你要更改的預設核心版本的位置 從0開始編號 順序。我的是 3,即第三個選項是舊核心...
使用配方更換型號
之前已經談過關於tr公司的產品換型的問題。但情況還是不滿意。故此,再次對該問題進行跟蹤。在昨天的測試中,如果直接用按鈕屬性中的下拉列表中的事件函式是無法找到新建記錄的系統函式的,但是通過對幫助文件中的系統函式進行查詢,找到了乙個配方檢視中新建記錄的類似函式。在後期的測試過程中發現該函式的確可以在當前...