通過金礦模型介紹動態規劃
= 2,所以程式執行時間為 t = o(questioncount * choosecount) =o(people * n),別忘了實際上需要的時間小於這個值,根據所遇到的具體情況有所不同。
這就是動態規劃的魔力,它減少了大量的計算,因此我們需要動態規劃!
----第三節----動態規劃的思考角度----------
那麼什麼是動態規劃呢?我個人覺得,如果乙個解決問題的方法滿足上面六個思考點中的前四個,那麼這個方法就屬於動態規劃。而在思考動態規劃方法時,後兩點同樣也是需要考慮的。
面對問題要尋找動態規劃的方法,首先要清楚一點,動態規劃不是演算法,它是一種方法,它是在一件事情發生的過程中尋找最優值的方法,因此,我們需要對這件事情所發生的過程進行考慮。而通常我們從過程的最後一步開始考慮,而不是先考慮過程的開始。
打個比方,上面的挖金礦問題,我們可以認為整個開採過程是從西至東進行開採的(也就是從第0座開始),那麼總有面對最後一座金礦的時候(第9座),對這座金礦不外乎兩個選擇,開採與不開採,在最後一步確定時再去確定倒數第二步,直到考慮第0座金礦(過程的開始)。
而過程的開始,也就是考慮的最後一步,就是邊界。
因此在遇到乙個問題想用動態規劃的方法去解決時,不妨先思考一下這個過程是怎樣的,然後考慮過程的最後一步是如何選擇的,通常我們需要自己去構造乙個過程,比如後面的練習。
----第四節----總結-------
那麼遇到問題如何用動態規劃去解決呢?根據上面的分析我們可以按照下面的步驟去考慮:
1、構造問題所對應的過程。
2、思考過程的最後乙個步驟,看看有哪些選擇情況。
3、找到最後一步的子問題,確保符合「子問題重疊」,把子問題中不相同的地方設定為引數。
4、使得子問題符合「最優子結構」。
5、找到邊界,考慮邊界的各種處理方式。
6、確保滿足「子問題獨立」,一般而言,如果我們是在多個子問題中選擇乙個作為實施方案,而不會同時實施多個方案,那麼子問題就是獨立的。
7、考慮如何做備忘錄。
8、分析所需時間是否滿足要求。
9、寫出轉移方程式。
----第五節----練習-------
題目一:買書
有一書店引進了一套書,共有3卷,每卷書定價是60元,書店為了搞**,推出乙個活動,活動如下:
如果單獨購買其中一捲,那麼可以打9.5折。
如果同時購買兩卷不同的,那麼可以打9折。
如果同時購買三卷不同的,那麼可以打8.5折。
如果小明希望購買第1卷x本,第2卷y本,第3卷z本,那麼至少需要多少錢呢?(x、y、z為三個已知整數)。
當然,這道題完全可以不用動態規劃來解,但是現在我們是要學習動態規劃,因此請想想如何用動態規劃來做?
答案:1、過程為一次一次的購買,每一次購買也許只買一本(這有三種方案),或者買兩本(這也有三種方案),或者三本一起買(這有一種方案),最後直到買完所有需要的書。
2、最後一步我必然會在7種購買方案中選擇一種,因此我要在7種購買方案中選擇乙個最佳情況。
3、子問題是,我選擇了某個方案後,如何使得購買剩餘的書能用最少的錢?並且這個選擇不會使得剩餘的書為負數。母問題和子問題都是給定三卷書的購買量,求最少需要用的錢,所以有「子問題重疊」,問題中三個購買量設定為引數,分別為i、j、k。
4、的確符合。
5、邊界是一次購買就可以買完所有的書,處理方式請讀者自己考慮。
6、每次選擇最多有7種方案,並且不會同時實施其中多種,因此方案的選擇互不影響,所以有「子問題獨立」。
7、我可以用minmoney[j][k]來儲存購買第1卷i本,第2卷j本,第3卷k本時所需的最少金錢。
8、共有x * y * z 個問題,每個問題面對7種選擇,時間為:o( x * y * z * 7) = o( 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,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行每行有兩個數,第i行的兩個數分別表示第i-1個金礦需要的人數和可以得到的金子數。
輸出檔案僅乙個整數,表示能夠得到的最大金子數。
輸入樣例:
100 5
77 92
22 22
29 87
50 46
99 90
輸出樣例:
133
動態規劃之深入淺出
動態規劃 dynamic programming,dp 演算法目的為解決多階段決策最優化問題,採取的方法是將待求解的問題分解為多個子問題,按順序求解每乙個子問題,當前子問題的解將由前乙個子問題的解推導出,最後乙個子問題就是初始問題的解。由於動態規劃解決的問題多數有重疊子問題這個特點,為減少重複計算,...
動態規劃之尼克的的任務
問題描述 尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完戍,尼克可以任選其中的乙個...
演算法入門之動態規劃的概念
演算法導論 中第15章這樣介紹動態規劃 動態規劃 dynamic programming 與分治法相似,都是通過組合子問題的解來求解原問題 在這裡,programming指的是一種 法,並非編寫電腦程式 如前述,分治法將問題劃分為互不相交的子問題,遞迴地求解子問題,再將它們的解組合起來,求出原問題的...