問題描述:
烙餅問題可以簡化為對一段由n個無重複的整數組成的無序陣列a[n]進行排序。排序要求每次只能對a[0]~a[i]部分的陣列進行翻轉(0 < i < n),最終完成排序。
輸入:陣列大小n;n個整數。
輸出:最小遞迴查詢次數m;每次翻轉位置j0j1…jm-1。
問題思考:
烙餅排序這部分,主要考量的是對遞迴函式的使用。
而搜尋上界與搜尋下界則可以一定程度上提高**的執行效率,減少搜尋次數。
遞迴流程如下:
①首先進行0~i的翻轉
②記錄第step步翻轉位置i
③然後進行下一層翻轉
④呼叫遞迴返回之後,再進行一次0~i的翻轉,保持陣列進入本次迴圈時的順序
①i++,進行0~i+1的翻轉
…
for
(int i =
1; i < m_ncakecnt; i++
)
稍微修改**之後可以發現,最小翻轉的解並不是唯一的。
測試輸入:10,
輸出有效最優解:
14849278
15183931
15218393
15839312
19385312
19465853
19484278
19615285
|search times| : 159193
total swap times = 8
完整**如下:
#include
#include
"stdafx.h"
#include
"afx.h"
class cprefixsorting
void
run(
int* pcakearray,
int ncakecnt)
//輸出烙餅具體翻轉的次數
void
output()
printf
("\n");
for(
int i =
0; i < m_nmaxswap; i++
)printf
("\n");
}printf
("\n |search times| : %d\n"
, m_nsearch)
;printf
("total swap times = %d\n"
, m_nmaxswap);}
private:
//初始化陣列資訊
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];}
//尋找翻轉上界
intupbound
(int ncakecnt)
//尋找翻轉下界
intlowerbound
(int
* pcakearray,
int ncakecnt)
else
}return ret;
}//排序主函式
void
search
(int step)
//如果已經排好序,即翻轉完成,輸出結果if(
issorted
(m_reversecakearray, m_ncakecnt)
)printf
("\n");
}return;}
//遞迴進行翻轉
for(
int i =
1; i < m_ncakecnt; i++)}
bool issorted
(int
* pcakearray,
int ncakecnt)
}return true;
}//翻轉烙餅資訊
void
revert
(int nbegin,
int nend)
}private:
int* m_ckaearray;
//烙餅資訊陣列
int m_ncakecnt;
//烙餅個數
int m_nmaxswap;
//最多交換次數,根據前面的推斷,這裡最多為m_ncakecnt*2
int* m_swaparray;
//交換結果陣列
int* m_reversecakearray;
//當前翻轉烙餅資訊陣列
int* m_reversecakearrayswap;
//當前翻轉烙餅交換結果陣列
int m_nsearch;
//當前搜尋次數資訊};
intmain()
; x.
run(array,10)
; x.
output()
;getchar()
;return0;
}
程式設計之美1 3 翻烙餅問題
問題 給定一組隨機數字,使其從大到小排序。要求 只能對陣列做一種操作 翻轉arr 0 至arr n 其中n為大於0小於arrlength的整數 解題思路 搜尋樹演算法 遞迴遍歷 減枝 詳解 1.將該陣列構建為一顆樹,假設該陣列為4,2,1,3 2.目標為如何找到序列為1,2,3,4 深度最小的子節點...
程式設計之美 烙餅問題
把一摞烙餅按大的在下,小的在上拍好,乙隻手一次只能抓住上面的幾張餅,把它們上下顛倒個個。反覆幾次後把餅排好。問把餅排好需要的最小的次數。問題 是看看把餅排好需要的最小次數。找最優解的問題,可以想到用窮舉法。用遞迴的方式去遍歷所有的翻轉方式。然後找到最小的值。可以先把最上面的兩張翻一下,把次數加一,看...
程式設計之美之烙餅問題
程式設計之美之一摞烙餅.cpp 定義控制台應用程式的入口點。不同的程式會得到不同的結果嗎?有個程式能得到不同的結果,但後來證明他的結果是錯的 該演算法有點在於在於找最少的交換次數,不是在於用最少的時間進行排序,此演算法的排序時間不是最少的。因為演算法的查詢時間太長了。include stdafx.h...