1 3 一摞烙餅的排序

2021-08-30 04:44:55 字數 2339 閱讀 4904

一摞亂序擺放的烙餅,每次只能抓取最上面幾塊烙餅並翻轉,多次翻轉後能夠實現烙餅的從小到大(從上往下)的有序擺放。

問題分析:

這裡我們使用回溯法解決這個問題。直接用回溯法效率是低下的,因此要進行剪枝。這裡的剪枝條件是利用翻轉次數的上界和下界完成的。

上界:[4,2,1,5,3] -> [5,1,2,4,3] -> [3,4,2,1,5]

兩步可以按大小順序將某塊餅放到它應該在的位置。

同理,可以把其他四塊烙餅擺放好,要注意最後一塊烙餅會在最後第二塊烙餅擺放正確後位於正確位置。假設烙餅個數為n,則翻轉次數上界為2(n-1)。

下界:上界我們已經得出了,下面考慮下界。在試驗翻轉的時候,我們可以發現,當烙餅堆部分有序時,翻轉次數較少。若一摞烙餅中有m對相鄰的烙餅半徑不相鄰,理想情況下需要m次翻轉來排序,[3,4,2,1,5,6],此時就需要兩次來翻轉。

**如下:

#include #include #include #include using namespace std;

class prefixsorting

~prefixsorting()

if(swaparray != null)

if(reversecakearray != null)

if(reversecakearrayswap != null)

}//計算烙餅翻轉資訊

//@param

//pcakearray 儲存烙餅索引陣列,索引大的烙餅個頭大

//pcakecount 烙餅個數

void run(int* pcakearray, int pcakecount)

void output()

//獲取最多交換次數

maxswap = upperbound(cakecount);

//初始化交換結果陣列

swaparray = new int[maxswap + 1];

assert(swaparray != null);

//初始化中間交換結果陣列

reversecakearray = new int[cakecount];

for(int i = 0; i < cakecount; i++)

reversecakearrayswap = new int[maxswap];

}//尋找當前翻轉上界

int upperbound(int pcakecount)

//尋找當前翻轉下界

int lowerbound(int* pcakearray, int pcakecount)

else

}return ret;

}//排序主函式

void search(int step)

//若已排好序則輸出結果

if(issorted(reversecakearray, cakecount))

return;}}

//回溯法遞迴翻轉

for(i = 1; i < cakecount; i++)

}//true: 已排序

//false: 未排序

bool issorted(int* pcakearray, int pcakecount)

}return true;

}//翻轉烙餅陣列

void reverse(int nbegin, int nend)

}private:

int* cakearray; //烙餅陣列

int cakecount; //烙餅個數

int maxswap; //交換次數上界

int* swaparray; //翻轉烙餅結果陣列(翻轉前幾層烙餅,用於輸出)

int* reversecakearray; //當前轉烙餅陣列(中間狀態)

int* reversecakearrayswap; //當前翻轉烙餅結果陣列

int nsearch; //當前搜尋次數

};int main()

; int cakecount = 5;

pfs.run(cakearray,cakecount);

pfs.output();

return 0;

}

注意:關於這裡的上下界,其實目前研究的結果是上界最小為(5n+5)/3向上取整,下界最大為15n/14向上取整。用這個上下界的搜尋次數更少,效率更高(n較大時)。

1 3 一摞烙餅的排序

假設有n塊大小不一樣的烙餅,那麼最少要翻動幾次,才能達到最終有序的結果。思路 每次找到最大的然後從將最大的以及最大的上面的反轉,這時候最大的在最上面,然後將整個反轉,最大的就在最下面了。然後再對除了最下面的n 1個烙餅進行上述的操作,知道全部的烙餅有序。例如 13524 53124 42135 cl...

一摞烙餅的排序(0621)

每乙個演算法都值得好好地分析 問題 假設有n塊大小不一的烙餅,那最少要翻幾次,才能達到最後大小有序的結果呢?這個排序問題非常有意思,首先我們要弄清楚解決問題的關鍵操作 單手每次抓幾塊餅,全部顛倒 每次我們只能選擇最上方的一堆餅,一起翻轉。而不能一張張地直接抽出來,然後進行插入,也不能交換任意兩塊餅子...

程式設計之美1 3 一摞烙餅的排序

程式設計之美 讀書筆記 1.3 一摞烙餅的排序 問題 星期五的晚上,一幫同事在希格瑪大廈附近的 硬碟酒吧 多喝了幾杯。程式設計師多喝了幾杯之後談什麼呢?自然是演算法問題。有個同事說 我以前在餐館打工,顧客經常點非常多的烙餅。店裡的餅大小不一,我習慣在到達顧客飯桌前,把一摞餅按照大小次序擺好 小的在上...