




下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、對于動態規劃,每個剛接觸的人都需要一段時間來理解,特別是第一次接觸的時候總是想不通為什么這種方法可行,這篇文章就是為了幫助大家理解動態規劃,并通過講解基本的01背包問題來引導讀者如何去思考動態規劃。本文力求通俗易懂,無異性,不讓讀者感到迷惑,引導讀者去思考,所以如果你在閱讀中發現有不通順的地方,讓你產生錯誤理解的地方:讓你難得讀懂的地方,請跟貼指出:謝謝!-第一節-初識動態規劃經典的01背包問題是這樣的:有一個包和n個物品,包的容量為m,每個物品都有各自的體積和價值,問當從這n個物品中選擇多個物品放在包里而物品體積總數不超過包的容量m時,能夠得到的最大價值是多少?對于每個物品不可以取多次,最多
2、只能取一次,之所以叫做01背包,0表示不取,1表示取為了用一種生動又更形象的方式來講解此題,我把此題用另一種方式來描述,如下:有一個國家,所有的國民都非常老實憨厚,某天他們在自己的國家發現了十座金礦,并且這十座金礦在地圖上排成一條直線,國王知道這個消息后非常高興,他希望能夠把這些金子都挖出來造福國民,首先他把這些金礦按照在地圖上的位置從西至東進行編號,依次為0、1、2、3、4、5、6、7、8、9,然后他命令他的手下去對每一座金礦進行勘測,以便知道挖取每一座金礦需要多少人力以及每座金礦能夠挖出多少金子,然后動員國民都來挖金子。題目補充1:挖每一座金礦需要的人數是固定的,多一個人少一個人都不行。國
3、王知道每個金礦各需要多少人手,金礦i需要的人數為peopleNeeded。題目補充2:每一座金礦所挖出來的金子數是固定的,當第i座金礦有peopleNeeded人去挖的話,就一定能恰好挖出gold個金子。否則一個金子都挖不出來。題目補充3:開采一座金礦的人完成開采工作后,他們不會再次去開采其它金礦,因此一個人最多只能使用一次。題目補充4:國王在全國范圍內僅招募到了10000名愿意為了國家去挖金子的人,因此這些人可能不夠把所有的金子都挖出來,但是國王希望挖到的金子越多越好。題目補充5:這個國家的每一個人都很老實(包括國王),不會私吞任何金子,也不會弄虛作假,不會說謊話。題目補充6:有很多人拿到這
4、個題后的第一反應就是對每一個金礦求出平均每個人能挖出多少金子,然后從高到低進行選擇,這里要強調這種方法是錯的,如果你也是這樣想的,請考慮背包模型,當有一個背包的容量為10,共有3個物品,體積分別是3、3、5,價值分別是6、6、9,那么你的方法取到的是前兩個物品,總價值是12,但明顯最大值是后兩個物品組成的15。題目補充7:我們只需要知道最多可以挖出多少金子即可,而不用關心哪些金礦挖哪些金礦不挖。那么,國王究竟如何知道在只有10000個人的情況下最多能挖出多少金子呢?國王是如何思考這個問題的呢?國王首先來到了第9個金礦的所在地(注意,第9個就是最后一個,因為是從0開始編號的,最西邊的那個金礦是第
5、0個),他的臣子告訴他,如果要挖取第9個金礦的話就需要1500個人,并且第9個金礦可以挖出8888個金子。聽到這里國王哈哈大笑起來,因為原先他以為要知道十個金礦在僅有10000個人的情況下最多能挖出多少金子是一件很難思考的問題,但是,就在剛才聽完他的臣子所說的那句話時,國王已經知道總共最多能挖出多少金子了,國王是如何在不了解其它金礦的情況下知道最多能挖出多少金子的呢?他的臣子們也不知道這個謎,因此他的臣子們就問他了:最聰明的國王陛下,我們都沒有告訴您其它金礦的情況,您是如何知道最終答案的呢?”得意的國王笑了笑,然后把他最得意的左、右手”叫到跟前,說到:我并不需要考慮最終要挖哪些金礦才能得到最多
6、的金子, 我只需要考慮我面前的這座金礦就可以了, 對于我面前的這座金礦不外乎僅有兩種選擇,要么挖,要么不挖,對吧?”當然,當然大臣們回答倒。國王繼續說道:如果我挖取第9座金礦的話那么我現在就能獲得8888個金子,而我將用去1500個人,那么我還剩下8500個人。我親愛的左部下,如果你告訴我當我把所有剩下的8500個人和所有剩下的其它金礦都交給你去開采你最多能給我挖出多少金子的話, 那么我不就知道了在第9個金礦一定開采的情況下所能得到的最大金幣數嗎?”國王的左部下聽后回答道:國王陛下,您的意思是如果我能用8500個人在其它金礦最多開采出x個金幣的話,那您一共就能夠獲得x+8888個金子,對嗎?”
7、是啊,是啊如果第9座金礦一定開采的話”大臣們點頭說到。國王笑著繼續對著他的右部下說到:親愛的右部下,也許我并不打算開采這第9座金礦,那么我依然擁有10000個人,如果我把這10000個人和剩下的金礦都給你的話,你最多能給我挖出多少個金子呢?”國王的右部下聰明地說道:尊敬的國王陛下,我明白您的意思了,如果我回答最多能購開采出y個金幣的話,那您就可以在y和x+8888之間選擇一個較大者,而這個較大者就是最終我們能獲得的最大金幣數,您看我這樣理解對嗎?”國王笑得更燦爛了,問他的左部下:那么親愛的左部下,我給你8500個人和其余金礦的話你能告訴我最多能挖出多少金子嗎?”請您放心,這個問題難不倒我左部下
8、向國王打包票說到。國王高興地繼續問他的右部下:那右部下你呢,如果我給你10000個人和其余金礦的話你能告訴我最多能挖出多少金子嗎?”當然能了!交給我吧!”右部下同左部下一樣自信地回答道。那就拜托給你們兩位了,現在我要回到我那舒適的王宮里去享受了,我期待著你們的答復;”國王說完就開始動身回去等消息了,他是多么地相信他的兩個大臣能夠給他一個準=確的答復,因為國王其實知道他的兩位大臣要比他聰明得多。故事發展到這里,你是否在想國王的這兩個大臣又是如何找到讓國王滿意的答案的呢?他們為什么能夠如此自信呢?事實上他們的確比國王要聰明一些,因為他們從國王的身上學到了一點,就是這一點讓他們充滿了自信。r國王走后
9、,國王的左、右部下來到了第8座金礦,早已在那里等待他們的金礦勘測兵向兩位大臣報道:聰明的兩位大臣,您們好,第8座金礦需要1000個人才能開采,可以獲彳導7000個金子”。因為國王僅給他的左部下8500個人,所以國王的左部下叫來了兩個人,對著其中一個人問到:如果我給你7500個人和除了第8、第9的其它所有金礦的話,你能告訴我你最多能挖出多少金子嗎?”然后國王的左部下繼續問另一個人:如果我給你8500個人和除了第8、第9的其它所有金礦的話,你能告訴我你最多能挖出多少金子嗎?”國王的左部下在心里想著:如果他們倆都能回答我的問題的話,那國王交給我的問題不就解決了嗎?哈哈哈!”因為國王給了他的右部下10
10、000個人,所以國王的右部下同樣也叫來了兩個人,對著其中一個人問:如果我給你9000個人和除了第8、第9的其它所有金礦的話,你能告訴我你最多能挖出多少金子嗎?”然后國王的右部下繼續問他叫來的另一個人:如果我給你10000個人和除了第8、第9的其它所有金礦的話,你能告訴我你最多能挖出多少金子嗎?”此時,國王的右部下同左部下一樣,他們都在為自己如此聰明而感到滿足。當然,這四個被叫來的人同樣自信地回答沒有問題,因為他們同樣地從這兩個大臣身上學到了相同的一點,而兩位自認為自己一樣很聰明的大臣得意地笑著回到了他們的府邸,等著別人回答他們提出來的問題,現在你知道了這兩個大臣是如何解決國王交待給他們的問題了
11、嗎?那么你認為被大臣叫去的那四個人又是怎么完成大臣交給他們的問題的呢?答案當然是他們找到了另外八個人!沒用多少功夫,這個問題已經在全國傳開了,更多人的人找到了更更多的人來解決這個問題,而有些人卻不需要去另外找兩個人幫他,哪些人不需要別人的幫助就可以回答他們的問題呢?很明顯,當被問到給你z個人和僅有第0座金礦時最多能挖出多少金子時,就不需要別人的幫助,因為你知道,如果z大于等于挖取第0座金礦所需要的人數的話,那么挖出來的最多金子數就是第0座金礦能夠挖出來的金子數,如果這z個人不夠開采第0座金礦,那么能挖出來的最多金子數就是0,因為這唯一的金礦不夠人力去開采。讓我們為這些不需要別人的幫助就可以準確
12、地得出答案的人們鼓掌吧,這就是傳說中的底層勞動人民!故事講到這里先暫停一下,我們現在重新來分析一下這個故事,讓我們對動態規劃有個理性認識。子問題:國王需要根據兩個大臣的答案以及第9座金礦的信息才能判斷出最多能夠開采出多少金子。為了解決自己面臨的問題,他需要給別人制造另外兩個問題,這兩個問題就是子問題。思考動態規劃的第一點-最優子結構:國王相信,只要他的兩個大臣能夠回答出正確的答案(對于考慮能夠開采出的金子數,最多的也就是最優的同時也就是正確的),再加上他的聰明的判斷就一定能得到最終的正確答案。我們把這種子問題最優時母問題通過優化選擇后一定最優的情況叫做最優子結構思考動態規劃的第二點-子問題重疊
13、:實際上國王也好,大臣也好,所有人面對的都是同樣的問題,即給你一定數量的人,給你一定數量的金礦,讓你求出能夠開采出來的最多金子數。我們把這種母問題與子問題本質上是同一個問題的情況稱為子問題重疊然而問題中出現的不同點往往就是被子問題之間傳遞的參數,比如這里的人數和金礦數。思考動態規劃的第三點-邊界:想想如果不存在前面我們提到的那些底層勞動者的話這個問題能解決嗎?永遠都不可能!我們把這種子問題在一定時候就不再需要提出子子問題的情況叫做邊界,沒有邊界就會出現死循環。思考動態規劃的第四點-子問題獨立:要知道,當國王的兩個大臣在思考他們自己的問題時他們是不會關心對方是如何計算怎樣開采金礦的,因為他們知道
14、,國王只會選擇兩個人中的一個作為最后方案,另一個人的方案并不會得到實施,因此一個人的決定對另一個人的決定是沒有影響的。我們把這種一個母問題在對子問題選擇時,當前被選擇的子問題兩兩互不影響的情況叫做子問題獨立”。這就是動態規劃,具有最優子結構”、子問題重疊“、邊界”和子問題獨立:當你發現你正在思考的問題具備這四個性質的話,那么恭喜你,你基本上已經找到了動態規劃的方法。有了上面的這幾點,我們就可以寫出動態規劃的轉移方程式,現在我們來寫出對應這個問題的方程式,如果用goldmineNum表示第mineNum個金礦能夠挖出的金子數,用peopleNeededmineNum表示挖第mineNum個金礦需
15、要的人數, 用函數f(people,mineNum)表示當有people個人和編號為0、1、2、3、mineNum的金礦時能夠得到的最大金子數的話,f(people,mineNum)等于什么呢?或者說f(people,mineNum)的轉移方程是怎樣的呢?答案是:當mineNum=0且people=peopleNeededmineNum時f(people,mineNum)goldmineNum當mineNum=0且peoplepeopleNeededmineNum時f(people,mineNum)=0當mineNum!=0時f(people,mineNum)=f(people-peopleN
16、eededmineNum,mineNum-1)+goldmineNum與f(people,mineNum-1)中的較大者,前兩個式子對應動態規劃的邊界”,后一個式子對應動態規劃的最優子結構”請讀者弄明白后再繼續往下看。-第二節-動態規劃的優點現在我假設讀者你已經搞清楚了為什么動態規劃是正確的方法,但是我們為什么需要使用動態規劃呢?請先繼續欣賞這個故事:國王得知他的兩個手下使用了和他相同的方法去解決交代給他們的問題后,不但沒有認為他的兩個大臣在偷懶,反而很高興,因為他知道,他的大臣必然會找更多的人一起解決這個問題,而更多的人會找更更多的人,這樣他這個聰明的方法就會在不經意間流傳開來,而全國人民都
17、會知道這個聰明的方法是他們偉大的國王想出來的,你說國王能不高興嗎?但是國王也有一些擔憂,因為他實在不知道這個工程”要動用到多少人來完成,如果幫助他解決這個問題的人太多的話那么就太勞民傷財了。會不會影響到今年的收成呢?”國王在心里想著這個問題,于是他請來了整個國家里唯一的兩個數學天才,一個叫做小天,另一個叫做小才。國王問小天:小天啊,我發覺這個問題有點嚴重,我知道其實這可以簡單的看成一個組合問題,也就是從十個金礦中選取若干個金礦進行開采,看看哪種組合得到的金子最多,也許用組合方法會更好一些。你能告訴我一共有多少種組合情況嗎?”國王陛下,如果用組合方法的話一共要考慮2的10次方種情況,也就是102
18、4種情況。小天思考了一會回答到。嗯,如果每一種情況我交給一個人去計算能得到的金子數的話,那我也要1024個人,其實還是挺多的?!眹鹾孟裨俅胃杏X到了自己的方法是正確的。國王心理期待著小才能夠給它一個更好的答案,問到:小才啊,那么你能告訴我用我的那個方法總共需要多少人嗎?其實,我也計算過,好像需要的人數是1+2+4+8+16+32+64+,畢竟每一個人的確都需要找另外兩個人來幫助他們”不辜負國王的期待,小才微笑著說到:親愛的國王陛下,其實我們并不需要那么多人,因為有很多問題其實是相同的,而我們只需要為每一個不同的問題使用一個人力便可。國王高興的問到:此話如何講?”打個比方,如果有一個人需要知道1
19、000個人和3個金礦可以開采出多少金子,同時另一個人也需要知道1000個人和3個金礦可以開采出多少金子的話,那么他們可以去詢問相同的一個人,而不用各自找不同的人浪費人力了?!眹跛伎贾f到:嗯,很有道理,如果問題是一樣的話那么就不需要去詢問兩個不同的人了,也就是說一個不同的問題僅需要一個人力,那么一共有多少個不同的問題呢?”因為每個問題的人數可以從0取到10000,而金礦數可以從0取到10,所以最多大約有10000*10等于100000個不同的問題。”小才一邊算著一邊回答。件么?十萬個問題?十萬個人力?”國王有點失望。請國王放心,事實上我們需要的人力遠遠小于這個數的,因為不是每一個問題都會遇到
20、,也許我們僅需要一、兩百個人力就可以解決這個問題了,這主要和各個金礦所需要的人數有關?!毙〔帕⒖袒卮鸬?。故事的最后,自然是國王再一次向他的臣民們證明了他是這個國家里最聰明的人,現在我們通過故事的第二部分來考慮動態規劃的另外兩個思考點。思考動態規劃的第五點-做備忘錄:正如上面所說的一樣,當我們遇到相同的問題時,我們可以問同一個人。講的通俗一點就是,我們可以把問題的解放在一個變量中,如果再次遇到這個問題就直接從變量中獲得答案,因此每一個問題僅會計算一遍,如果不做備忘的話,動態規劃就沒有任何優勢可言了。思考動態規劃的第六點-時間分析:正如上面所說,如果我們用窮舉的方法,至少需要2個常數時間,因為總共
21、有2種情況需要考慮,如果在背包問題中,包的容量為1000,物品數為100,那么需要考慮2A100種情況,這個數大約為10的30次方。而如果用動態規劃,最多大概只有1000*100=100000個不同的問題,這和10的30次方比起來優勢是很明顯的。而實際情況并不會出現那么多不同的問題,比如在金礦模型中,如果所有的金礦所需人口都是1000個人,那么問題總數大約只有100個。非正式地,我們可以很容易得到動態規劃所需時間,如果共有questioncount個相同的子問題,而每一個問題需要面對chooseCount種選擇時,我們所需時間就為questionCount*chooseCount個常數。在金礦
22、模型中,子問題最多有大概people*n個(其中people是用于開采金礦的總人數,n是金礦的總數),因此questionCount=people*n,而就像國王需要考慮是采用左部下的結果還是采用右部下的結果一樣,每個問題面對兩個選擇,因此chooseCount=2,所以程序運行時間為T=O(questionCount*chooseCount)=O(people*n),別忘了實際上需要的時間小于這個值,根據所遇到的具體情況有所不同。這就是動態規劃的魔力,它減少了大量的計算,因此我們需要動態規劃!-第三節-動態規劃的思考角度那么什么是動態規劃呢?我個人覺得,如果一個解決問題的方法滿足上面六個思考
23、點中的前四個,那么這個方法就屬于動態規劃。而在思考動態規劃方法時,后兩點同樣也是需要考慮的。面對問題要尋找動態規劃的方法,首先要清楚一點,動態規劃不是算法,它是一種方法,它是在一件事情發生的過程中尋找最優值的方法,因此,我們需要對這件事情所發生的過程進行考慮。而通常我們從過程的最后一步開始考慮,而不是先考慮過程的開始。打個比方,上面的挖金礦問題,我們可以認為整個開采過程是從西至東進行開采的(也就是從第0座開始),那么總有面對最后一座金礦的時候(第9座),對這座金礦不外乎兩個選擇,開采與不開采,在最后一步確定時再去確定倒數第二步,直到考慮第0座金礦(過程的開始)。而過程的開始,也就是考慮的最后一
24、步,就是邊界。因此在遇到一個問題想用動態規劃的方法去解決時,不妨先思考一下這個過程是怎樣的,然后考慮過程的最后一步是如何選擇的,通常我們需要自己去構造一個過程,比如后面的練習。-第四節-總結那么遇到問題如何用動態規劃去解決呢?根據上面的分析我們可以按照下面的步驟去考慮:1、構造問題所對應的過程。2、思考過程的最后一個步驟,看看有哪些選擇情況。3、找到最后一步的子問題,確保符合子問題重疊:把子問題中不相同的地方設置為o4、使得子問題符合最優子結構”。一5、找到邊界,考慮邊界的各種處理方式。6、確保滿足子問題獨立,一般而言,如果我們是在多個子問題中選擇一個作為實施方案,而不會同時實施多個方案,那么
25、子問題就是獨立的。7、考慮如何做備忘錄。8、分析所需時間是否滿足要求。9、寫出轉移方程式。-第五節-練習題目一:買書有一書店引進了一套書,共有3卷,每卷書定價是60元,書店為了搞促銷,推出一個活動,活動如下:如果單獨購買其中一卷,那么可以打9.5折。如果同時購買兩卷不同的,那么可以打9折。如果同時購買三卷不同的,那么可以打8.5折。如果小明希望購買第1卷x本,第2卷y本,第3卷z本,那么至少需要多少錢呢?(x、v、z為三個已知整數)。當然,這道題完全可以不用動態規劃來解,但是現在我們是要學習動態規劃,因此請想想如何用動態規劃來做?答案:1、過程為一次一次的購買,每一次購買也許只買一本(這有三種
26、方案),或者買兩本(這也有三種方案),或者三本一起買(這有一種方案),最后直到買完所有需要的書。2、最后一步我必然會在7種購買方案中選擇一種,因此我要在7種購買方案中選擇一個最佳情況。3、子問題是,我選擇了某個方案后,如何使得購買剩余的書能用最少的錢?并且這個選擇不會使得剩余的書為負數。母問題和子問題都是給定三卷書的購買量,求最少需要用的錢,所以有子問題重疊”,問題中三個購買量設置為參數,分別為i、j、k。4、的確符合。5、邊界是一次購買就可以買完所有的書,處理方式請讀者自己考慮。6、每次選擇最多有7種方案,并且不會同時實施其中多種,因此方案的選擇互不影響,所以有子問題獨立7、我可以用minM
27、oneyjk來保存購買第1卷i本,第2卷j本,第3卷k本時所需的最少金錢。8、共有x*y*z個問題,每個問題面對7種選擇,時間為:O(x*y*z*7)=0(x*y*z)9、用函數MinMoney(i,j,k)來表示購買第1卷i本,第2卷j本,第3卷k本時所需的最少金錢,那么有:MinMoney(i,j,k)=min(s1,s2,s3,s4,s5,s6,s7),其中s1,s2,s3,s4,s5,s6,s7分別為對應的7種方案使用的最少金錢:s1=60*0.95+MinMoney(i-1,j,k)s2=60*0.95+MinMoney(i,j-1,k)s3=60*0.95+MinMoney(i,j
28、,k-1)s4=(60+60)*0.9+MinMoney(i-1,j-1,k)s5=(60+60)*0.9+MinMoney(i-1,j,k-1)s6=(60+60)*0.9+MinMoney(i-1,j,k-1)s7=(60+60+60)*0.85+MinMoney(i-1,j-1,k-1)-第六節-代碼參考下面提供金礦問題的程序源代碼幫助讀者理解,并提供測試數據給大家練習。輸入文件名為“beibao.in,因為這個問題實際上就是背包問題,所以測試數據文件名就保留原名吧。輸入文件第一行有兩個數,第一個是國王可用用來開采金礦的總人數,第二個是總共發現的金礦數。二輸入文件的第2至n+1行每行有兩
29、個數,第i行的兩個數分別表示第i-1個金礦需要的人數和可以得到的金子數。輸出文件僅一個整數,表示能夠得到的最大金子數。輸入樣例:100577922222298750469990輸出樣例:1331.#includestdafx.h2.3.#include#includeusingnamespacestd;constintmax_n=100;/程序支持的最多金礦數constintmax_people=10000;/程序支持的最多人數intn;/金礦數intpeopleTotal;/可以用于挖金子的人數intpeopleNeedmax_n;/每座金礦需要的人數intgoldmax_n;/每座金礦能夠挖出來的金子數intmaxGoldmax_peoplemax_n;/maxGoldij保存了i個人挖前j個金礦能夠得到的最大金子數,等于-1時表示未知/初始化數據voidinit()ifstreaminputFile(beibao.in);inputFilepeopleTotaln;for(inti=0;ipeopleNeedigoldi;inputFile.close();4.5.6.7.8.9.10.11.12.13
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 恐龍展品租賃合同協議
- 商務房車租賃合同協議
- 兒童哮喘治療方法
- 急性心肌炎診斷和治療
- 2025至2031年中國異徑承口接頭行業投資前景及策略咨詢研究報告
- 有關治療腫瘤的多肽
- 二零二五辦公用品采購合同書
- 健康生活與環保正確處理日常醫療廢物
- 區塊鏈AI融合應用打造智能城市新生態
- 二零二五版綠色植物租賃合同書范文
- 2025商業綜合體委托經營管理合同書
- 2024-2025學年北師大版生物七年級下冊期中模擬生物試卷(含答案)
- T-CACM 1212-2019 中醫婦科臨床診療指南 產后小便不通
- 林業理論考試試題及答案
- 超市店長價格管理制度
- 2025-2030中國腦芯片模型行業市場發展趨勢與前景展望戰略研究報告
- 2025年河南省洛陽市洛寧縣中考一模道德與法治試題(含答案)
- 掘進爆破、爆破安全知識
- 綠色工廠員工培訓
- 2025年吉林省長春市中考一模歷史模擬試題(含答案)
- 貴州民族建筑知到智慧樹章節測試課后答案2024年秋貴州民族大學
評論
0/150
提交評論