問題描述:一摞大小不一的餅,由於乙隻手托著盤子,只好用另乙隻手,一次抓住最上面的幾塊餅,把它們上下顛倒個,反覆幾次使烙餅安裝由小到大排好序。假設有n塊大小不一的餅,最少需要翻幾次使烙餅排好序。
分析與解法:
首先,經過兩次翻轉可以把最大的烙餅翻轉到最下面,因此,最多需要把上面的n-1個烙餅依次翻轉兩次。那麼至多需2(n-1)次翻轉就可以把所有烙餅排好序。當然還有更高效的方法,考慮每次翻轉的時候,把兩個本來應該相鄰的烙餅盡可能的換到一起,當所有的烙餅都換到一起時,實際上已經完成了排序。因此,可以通過遞迴來進行求解。
遞迴的第乙個退出條件是已經排好序,還有就是翻轉次數多於2(n-1)就退出。在翻轉的過程中,可以看看當前的烙餅陣列的排序情況如何,然後利用這些資訊幫助減少翻轉次數。
每個狀態還應該有翻轉的最小次數,這個下限值可以這樣確定:從最後乙個位置開始,往前找到第乙個與最終結果位置不同的烙餅編號(也就是說排除最後幾個已經就位的烙餅),從該位置到第乙個位置,計算相鄰的烙餅的編號不連續的次數,再加上1
。**如下:
#include#includeclass cprefixsorting
//計算烙餅翻轉資訊
//@param
//pcakearray 儲存烙餅索引陣列
//ncakecnt 烙餅個數
void run(int* pcakearray,int ncakecnt)
//輸出烙餅具體翻轉次數
void output()
printf("\n |search times| : %d\n", m_nsearch);
printf("total swap times = %d\n", m_nmaxswap);
}private:
////初始化陣列資訊
//@param
//pcakearray 儲存烙餅索引陣列
//ncakecnt 烙餅個數
//void init(int* pcakearray,int ncakecnt)
//設定最多交換次數資訊
m_nmaxswap = upbound(m_ncakecnt);
//初始化交換結果陣列
m_swaparray = new int[m_nmaxswap];
assert(m_swaparray != null);
//初始化中間交換結果資訊
m_reversecakearray = new int[m_ncakecnt];
for(int i = 0; i < m_ncakecnt; i++)
m_reversecakearrayswap = new int[m_nmaxswap];}//
//尋找當前翻轉的上界
////
int upbound(int ncakecnt)
////尋找當前翻轉的下界
////
int lower_bound(int* pcakearray,int ncakecnt)
else
}return ret;
}// 排序的主函式
void search(int step)
return;
}//遞迴進行翻轉
for(int i = 1; i < m_ncakecnt; i++)}//
//true: 已經排好序
//false: 未排序
//bool issorted(int* pcakearray,int ncakecnt)
}return true;}//
//翻轉烙餅資訊
//void revert(int nbegin,int nend)
}private:
int* m_cakearray; //烙餅資訊陣列
int m_ncakecnt; //烙餅個數
int m_nmaxswap; //最多交換次數,根據前面的推斷,這裡最多為m_ncakecnt*2
int* m_swaparray; //交換結果陣列
int* m_reversecakearray; //當前翻轉烙餅資訊陣列
int* m_reversecakearrayswap; //當前翻轉烙餅交換結果陣列
int m_nsearch; //當前搜尋次數資訊
};int main()
; cpfs.run(cakearray,6);
cpfs.output();
}
《程式設計之美》讀書筆記02 1 3 一摞烙餅的排序
程式設計之美 讀書筆記02 1.3 一摞烙餅的排序 問題 星期五的晚上,一幫同事在希格瑪大廈附近的 硬碟酒吧 多喝了幾杯。程式設計師多喝了幾杯之後談什麼呢?自然是演算法問題。有個同事說 我以前在餐館打工,顧客經常點非常多的烙餅。店裡的餅大小不一,我習慣在到達顧客飯桌前,把一摞餅按照大小次序擺好 小的...
一摞烙餅的排序(0621)
每乙個演算法都值得好好地分析 問題 假設有n塊大小不一的烙餅,那最少要翻幾次,才能達到最後大小有序的結果呢?這個排序問題非常有意思,首先我們要弄清楚解決問題的關鍵操作 單手每次抓幾塊餅,全部顛倒 每次我們只能選擇最上方的一堆餅,一起翻轉。而不能一張張地直接抽出來,然後進行插入,也不能交換任意兩塊餅子...
1 3 一摞烙餅的排序
一摞亂序擺放的烙餅,每次只能抓取最上面幾塊烙餅並翻轉,多次翻轉後能夠實現烙餅的從小到大 從上往下 的有序擺放。問題分析 這裡我們使用回溯法解決這個問題。直接用回溯法效率是低下的,因此要進行剪枝。這裡的剪枝條件是利用翻轉次數的上界和下界完成的。上界 4,2,1,5,3 5,1,2,4,3 3,4,2,...