日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

编程之美学习笔记(三):一摞烙饼的排序

發(fā)布時(shí)間:2023/12/8 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编程之美学习笔记(三):一摞烙饼的排序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問題描述

星期五的晚上,一幫同事在希格瑪大廈附近的“硬盤酒吧”多喝了幾杯,程序員多喝了幾杯之后談什么呢?自然是算法

題。有個(gè)同事說:

“我以前在餐廳打工,顧客經(jīng)常點(diǎn)非常多的烙餅。店里的烙餅大小不一,我習(xí)慣在到達(dá)顧客飯桌前,把一摞餅按照大小

次序擺好---小的在上面,大的在下面。由于我一只手托著盤子,只好用另一只手,一次抓住最上面的幾塊餅,把它們

下顛倒個(gè)個(gè)兒,反復(fù)幾次之后,這摞烙餅就排好序了。我后來想,這實(shí)際上是個(gè)有趣的排序問題:假設(shè)有n塊大小

不一的摞餅,那最少要翻幾次,才能達(dá)到大小有序的結(jié)果呢?

從這段描述中我們可以很容易的就把問題抽象出來:給你一個(gè)由 n 個(gè)連續(xù)整數(shù)組成的數(shù)組,數(shù)組是無序的,現(xiàn)在要你

對(duì)這個(gè)數(shù)組進(jìn)行升序排序,但只能對(duì)數(shù)組進(jìn)行一種操作,就是只能對(duì)從數(shù)組第一個(gè)元素開始到數(shù)組中任意一個(gè)元素之

間的所有元素進(jìn)行翻轉(zhuǎn)。只是這樣的話,問題還不是很麻煩。這里還要求我們寫程序輸出最優(yōu)的翻轉(zhuǎn)過程。


思路:

一般遇到最優(yōu)解問題我們首先想到的就是動(dòng)態(tài)規(guī)劃、貪心以及分支界限三種方法。書中提到了動(dòng)態(tài)規(guī)劃和分支界限這

兩種方法,但只給出了分支界限方法的思路以及代碼,所以我就以書上的方法來講講自己的理解吧。

書上的代碼用的是遞歸遍歷+剪枝。既然是遞歸,就得有個(gè)退出的條件,不然就死循環(huán)了。在這個(gè)問題中,第一個(gè)遞

歸退出的條件理所當(dāng)然就是所有的烙餅都已經(jīng)排好序了。如果只是這樣的,就不涉及到剪枝了。我們知道遞歸的特點(diǎn)

是簡(jiǎn)潔,但是其效率相對(duì)來說是比較低的,如果遇到很大的問題,在現(xiàn)實(shí)中就不適用了,而提高遞歸效率的唯一方法

就是剪枝,所以我們必須想辦法找到剪枝的策略。


一般來說我們都是通過去除一些不必要的遍歷來進(jìn)行剪枝的,分析這個(gè)問題,我們不難發(fā)現(xiàn),最多要翻轉(zhuǎn)的次數(shù)不會(huì)

超過2*(n-1)次,至于這個(gè)數(shù)字是怎么來的,書上已經(jīng)寫的很明白了,這里就不多作累贅啦。如果只是等某種翻轉(zhuǎn)次數(shù)

超過2*(n-1)再來放棄這種遍歷的話,顯然意義不大。按照書上給出的思路,以2*(n-1)作為上界(UpperBound),表

示最差方案;而下界(LowerBound)則是動(dòng)態(tài)的,下界的取值是當(dāng)前排序狀態(tài)下,我們至少還要翻轉(zhuǎn)的次數(shù),程序

中我們用變量 nEstimate ?表示。當(dāng)當(dāng)前翻轉(zhuǎn)次數(shù)+nEstimate>UpperBound()時(shí),說明繼續(xù)遍歷下去最后的結(jié)果會(huì)超過

上界,這時(shí)我們直接對(duì)其進(jìn)行剪枝。


代碼:

#include<cassert> #include<iostream> using namespace std;class PrefixSorting {int* m_CakeArray; //烙餅信息數(shù)組int m_nCakeCnt; //烙餅個(gè)數(shù)int m_nMaxSwap; //最多翻轉(zhuǎn)次數(shù),即上界int* m_SwapArray; //交換結(jié)果數(shù)組,即保存最優(yōu)解的每一步交換int* m_ReverseCakeArray; //當(dāng)前翻轉(zhuǎn)烙餅信息數(shù)組int* m_ReverseCakeArraySwap; //當(dāng)前翻轉(zhuǎn)烙餅交換結(jié)果數(shù)組int m_nSearch; //當(dāng)前遍歷次數(shù)信息 public:PrefixSorting(){m_nCakeCnt = 0;m_nMaxSwap = 0;}~PrefixSorting(){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;}/*計(jì)算烙餅翻轉(zhuǎn)信息*/void Run(int* pCakeArray, int nCakeCnt){Init (pCakeArray, nCakeCnt);m_nSearch = 0;Search (0);}/*輸出烙餅翻轉(zhuǎn)的具體信息*/void Output (){for (int i = 0; i < m_nMaxSwap; i++)printf("%d\n", m_SwapArray[i]);printf("Search Times : %d\n", m_nSearch);printf("Total Swap times = %d\n", m_nMaxSwap);}private:void Init(int* pCakeArray, int nCakeCnt){assert (pCakeArray != NULL);assert (nCakeCnt > 0);m_nCakeCnt = nCakeCnt;m_CakeArray = new int[m_nCakeCnt];assert (m_CakeArray != NULL);for (int i = 0; i < m_nCakeCnt; i++){m_CakeArray[i] = pCakeArray[i];}m_nMaxSwap = UpperBound (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_ReverseCakeArray[i] = m_CakeArray[i];}m_ReverseCakeArraySwap = new int[m_nMaxSwap];}/*計(jì)算上界*/int UpperBound(int nCakeCnt){return (nCakeCnt - 1) * 2; //書上這里是 nCakeCnt * 2}/*計(jì)算下界*/int LowerBound(int* pCakeArray, int nCakeCnt){int t;int ret = 0;for (int i = 1; i < nCakeCnt; i++){t = pCakeArray[i] - pCakeArray[i - 1];if ((t == 1) || (t == -1)){}else{ret++;}}return ret;}/*排序的主函數(shù)*/void Search(int step){int i, nEstimate;m_nSearch++;/*剪枝*/nEstimate = LowerBound (m_ReverseCakeArray, m_nCakeCnt);if (step + nEstimate >= m_nMaxSwap)return ;/*如果已經(jīng)排好序,輸出結(jié)果*/if (IsSorted(m_ReverseCakeArray, m_nCakeCnt)){if (step < m_nMaxSwap){m_nMaxSwap = step;for (i = 0; i < m_nMaxSwap; i++)m_SwapArray[i] = m_ReverseCakeArraySwap[i];}return ;}/*遞歸遍歷*/for (int i = 1; i < m_nCakeCnt; i++){Reverse (0, i);m_ReverseCakeArraySwap[step] = i;Search (step + 1);Reverse (0, i);}}/*判斷是否已經(jīng)排好序*/bool IsSorted(int* pCakeArray, int nCakeCnt){for (int i = 1; i < nCakeCnt; i++){if (pCakeArray[i - 1] > pCakeArray[i])return false;}return true;}/*翻轉(zhuǎn)烙餅*/void Reverse(int nBegin, int nEnd){assert (nEnd > nBegin);int i, j, t;for (i = nBegin, j = nEnd; i < j; i++, j--){t = m_ReverseCakeArray[i];m_ReverseCakeArray[i] = m_ReverseCakeArray[j];m_ReverseCakeArray[j] = t;}} };int main() {int a[] = {3, 2, 1, 6, 5, 4, 9, 8, 7, 0};PrefixSorting test;test.Run(a, 10);test.Output();system("pause");return 0; }


總結(jié)

以上是生活随笔為你收集整理的编程之美学习笔记(三):一摞烙饼的排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩中文字幕av电影 | 花房姑娘免费观看全集 | 色综合久久久久综合体桃花网 | 爱情岛成人 | 日少妇av| 精品国产黄 | 成年人在线视频免费观看 | 亚洲乱亚洲乱 | 2020自拍偷拍| 亚洲综合在线播放 | 69xxx国产| 自拍偷拍欧美亚洲 | 亚洲第五页 | 国产精品又黄又爽又色无遮挡 | xxav在线 | av在线播放网址 | 中文字幕人妻一区二区三区 | 天堂va蜜桃 | 精品人伦一区二区三区蜜桃免费 | 99福利网 | jizz欧美大全 | 成人动漫在线观看视频 | jizz在亚洲 | 91视频插插插 | 国产精品无码AV无码国产 | 97爱爱爱 | 婷婷九月综合 | 亚洲欧美另类综合 | 日本三级中国三级99人妇网站 | 伊人免费在线观看高清版 | 亚洲 欧美 自拍偷拍 | 欧美日韩一区二区在线观看视频 | 四虎影院成人 | 日韩中文电影 | 女同vk | 亚洲成人一区在线 | 中文字字幕在线中文 | 久热免费在线视频 | 高h文在线 | 中文天堂网 | 欧美一区二区视频在线观看 | 精东影业一区二区三区 | 欧美精品卡一卡二 | 久久久久99精品成人片 | 亚洲欧美在线观看视频 | 日产精品久久久一区二区 | 日本理论片 | 亚洲精品一二三四区 | 日本黄色精品 | 李宗瑞91在线正在播放 | 一区二区三区精品在线 | 日本在线成人 | 日韩免费在线视频观看 | 国产精品免费无遮挡无码永久视频 | 波多野结衣丝袜 | 国产女主播喷水视频在线观看 | 综合视频在线观看 | 欧美韩国日本一区 | 国产一区二区精彩视频 | 91伊人| 精品人妻午夜一区二区三区四区 | 欧美午夜三级 | 国产一级二级三级精品 | 女人的黄色片 | 成人免费短视频 | 极品美妇后花庭翘臀娇吟小说 | 精品久久999 | 奇米影视一区 | 国产偷人妻精品一区 | 韩日精品在线观看 | 催眠调教后宫乱淫校园 | 一道本无吗一区 | 欧美a视频在线观看 | 亚洲免费不卡视频 | 日批黄色 | 亚洲欧美国产高清va在线播放 | 黄色在线免费观看 | 中文字幕欧美另类精品亚洲 | 日韩av一区二区三区 | 日本69熟 | 欧美干干干 | 99久久久国产精品无码免费 | www.蜜臀av| 潘金莲一级淫片aaaaaa播放 | 亚洲激情在线播放 | 国产精品69久久久久 | 色播视频在线观看 | 成人免费激情视频 | 黄色一级片视频 | 欧美另类xxxxx | 中文久久乱码一区二区 | 97精品久久| 成人亚洲玉足脚交系列 | 91免费播放 | 漂亮人妻被中出中文字幕 | 亚洲第一成人在线 | 成人亚洲国产 | 亚洲国产剧情在线观看 | 欧美成人精品一区二区男人看 |