一摞亂序擺放的烙餅,每次只能抓取最上面幾塊烙餅並翻轉,多次翻轉後能夠實現烙餅的從小到大(從上往下)的有序擺放。
問題分析:
這裡我們使用回溯法解決這個問題。直接用回溯法效率是低下的,因此要進行剪枝。這裡的剪枝條件是利用翻轉次數的上界和下界完成的。
上界:[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 一摞烙餅的排序 問題 星期五的晚上,一幫同事在希格瑪大廈附近的 硬碟酒吧 多喝了幾杯。程式設計師多喝了幾杯之後談什麼呢?自然是演算法問題。有個同事說 我以前在餐館打工,顧客經常點非常多的烙餅。店裡的餅大小不一,我習慣在到達顧客飯桌前,把一摞餅按照大小次序擺好 小的在上...