The question is as follows:
On Friday evening, a group of colleagues drank a few more drinks at the hard drive bar near the higemma building. What do programmers talk about after a few more drinks? Naturally, it is an algorithm problem. A colleague said:
"I used to work in a restaurant and customers often ordered a lot of pancakes.The size of the pie in the store is different.I used to set a pile of cakes in order of size before arriving at the customer's dinner table-small and big. Because I held the plate with one hand, I had to use the other hand. I grabbed the top cakes and turned them upside down. After several times, the order is arranged.
I later thought that this is actually an interesting Sorting Problem:Assume thatNFor a pancake of different sizes, How many times should it be turned over to achieve the final size order?
Thoughts:
The method provided in the book is to find the optimal solution through recursion.
There are two recursive end conditions:
1) The number of recursive steps exceeds the maximum;
2) It has been ordered.
However, because there are too many steps in the recursive process, You Need To pruning it:
1) Upper Bound: assume that only the maximum value is pushed to the bottom (similar to the bubble) at a time, and at most two flipped s are required. A total of N-1 ones need to be flipped (the last one does not need to be flipped ), therefore, a maximum of 2 * (n-1) flipped steps are required. Of course, to reduce unnecessary traversal, each time you find a step that achieves an ordered number of steps, update Max to this step.
2) lower bound: calculates the minimum number of times that the current State needs to be flipped during each recursion and is set to lowerbound, if the number of currently flipped steps Step + lowerbound (number of flipped steps + at least the number of required steps in the current State) exceeds the upper limit, this recursion can be ended.
Code:
Class cprefixsorting {public: cprefixsorting () {m_ncakecnt = 0; m_nmaxswap = 0 ;}~ Cprefixsorting () {If (m_cakearray! = NULL) delete m_cakearray; If (m_swaparray! = NULL) delete m_swaparray; If (m_reversecakearray! = NULL) delete m_reversecakearray; If (m_reversecakearrayswap! = NULL) delete m_reversecakearrayswap;} // pcakearray storage pancake Index Array // ncakecnt pancake count void run (int * pcakearray, int ncakecnt) {Init (pcakearray, ncakecnt ); m_nsearch = 0; search (0);} // number of times the pancake is flipped void output () {for (INT I = 0; I <m_nmaxswap; ++ I) cout <m_swaparray [I] <"; cout <" Search times: "<m_nsearch; cout <" Total swap times: "<m_nmaxswap;} PRIVATE: // pcakearray storage pancake Index Array // ncakecnt pancake count void Init (I Nt * pcakearray, int ncakecnt) {assert (pcakearray! = NULL); Assert (ncakecnt> 0); m_ncakecnt = ncakecnt; // initialize the pancake array m_cakearray = new int [ncakecnt]; Assert (m_cakearray! = NULL); For (INT I = 0; I <ncakecnt; ++ I) m_cakearray [I] = pcakearray [I]; // set the maximum number of exchanges m_nmaxswap = upperbound (m_ncakecnt); // initialize the exchange result array m_swaparray = new int [m_nmaxswap + 1]; Assert (m_swaparray! = NULL); // initialize the intermediate exchange result information m_reversecakearray = new int [m_ncakecnt]; for (INT I = 0; I <m_ncakecnt; ++ I) m_reversecakearray [I] = m_cakearray [I]; reverse = new int [m_nmaxswap];} // search for the upper bound int upperbound (INT ncakecnt) {return ncakecnt * 2 ;} // find the lower bound int lowerbound (int * pcakearray, int ncakecnt) of the current flip {int ret = 0; // determine the minimum number of for (INT I = 1; I <ncakecnt; ++ I) based on the sorting information of the current array) {// determine whether the two adjacent pancakes are sorted by the size of the adjacent int T = pcakearray [I]-pcakearray [I-1]; if (t = 1 | T =-1) {} else ++ ret;} return ret;} void search (INT step) {m_nsearch ++; // estimate the minimum number of exchanges required for this search int nestimate = lowerbound (m_reversecakearray, m_ncakecnt); If (Step + nestimate> m_nmaxswap) return; // If the order has been sorted, that is, if (issorted (m_reversecakearray, m_ncakecnt) {If (Step <m_nmaxswap) {m_nmaxswap = step; For (INT I = 0; I <m_nmaxswap; ++ I) m_swaparray [I] = m_reversecakearrayswap [I];} return ;}// recursively flip for (INT I = 1; I <m_ncakecnt; ++ I) {reverse (0, I); m_reversecakearrayswap [STEP] = I; search (Step + 1); reverse (0, I) ;}} bool issorted (int * pcakearray, int ncakecnt) {for (INT I = 1; I <ncakecnt; ++ I) {If (pcakearray [I-1]> pcakearray [I]) return false;} return true ;} // void reverse (INT nbegin, int nend) {assert (nbegin <nend); // flip the pancake information for (INT I = nbegin, j = nend; I <j; ++ I, -- j) {int temp = m_reversecakearray [I]; m_reversecakearray [I] = m_reversecakearray [J]; m_reversecakearray [J] = temp ;}} PRIVATE: int * m_cakearray; // pancake information array int m_ncakecnt; // Number of pancakes int m_nmaxswap; // The maximum number of exchanges, based on the previous inference, here it can be m_ncakecnt * 2int * m_swaparray; // exchange result array int * m_reversecakearray; // The current flat information array int * m_reversecakearrayswap; // The current flat result array int m_nsearch; // current search times };
1.3 a stack of pancakes