題目來源:http://www.cnblogs.com/SDJL/category/154361.html
有一書店引進了一套書,共有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[i][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,j-1,k-1)
s7 = (60 + 60 + 60) * 0.85 +MinMoney(i-1,j-1,k-1)
分析:
我在看完金礦問題的分析之後,對動態規劃有了一個比較清晰的認識了,但是在看到這道練習題以及其答案分析之後,不知道什麼意思,不知道是我太笨還是怎麼回事,讓我想了將近半個小時才想明白,現將我的心得體會陳述如下:
在一開始我看到這個題的時候我就想,小明希望購買第1卷x本,第2卷y本,第3卷z本,這樣的話他就購買了一套書的三冊了。按理說這批書就應該可以打8.5折,但是這樣就沒有動態規劃的用武之地了。最後我又好好的想了想,其實店家打折的種類條件不是按照你這批書總的種類來分的,而是按照該批書能組合成多少套來分的,其打折條件是對每一套書來說的,不是對總的種類。比如:小明要購買第1卷1本,第2卷2本,第3卷3本,在不考慮用錢最少的情況下,店家會這樣計算書錢,第1卷1本,第2卷1本,第3卷1本這個組合能組合成一套書,滿足打折條件3。剩下第2卷1本,第3卷2本,可以組合成第2卷1本,第3卷1本,滿足打折條件2。最後剩一本第3卷,這樣就只滿足打折條件3。
本問題之所以要用動態規劃分析如下:
從中可以看出:
(1) 母問題A為給定總的買書量,我們要確定買這些書的最少花錢數,將這個母問題A分解為7個子問題,1…7,分別表示在買相應卷的情況下剩下部分所需的最少錢數。
(2) 當考慮子問題1時,其過程跟考慮母問題A是一樣的,這就是“子問題重疊”而且個子問題是相互獨立的,所以滿足“子問題獨立”。
(3) 在每一個子問題中選擇min組合,所以滿足“子問題最優”。
(4) 邊界就是把子問題劃分到最後所得到的形式,該形式為屬於“第1卷1本,第2卷1本,第3卷1本 ”這三種組合的某個可能組合,總共的組合數為(C31+C32+C33)。
(5) 以下跟作者雷同:
(6) 我可以用minMoney[i][j][k]來儲存購買第1卷i本,第2卷j本,第3卷k本時所需的最少金錢。
(7) 8、共有x * y * z個問題,每個問題面對7種選擇,時間為:O( x * y *z * 7) = O( x * y* z )。
(8) 用函數MinMoney(i,j,k)來表示購買第1卷i本,第2卷j本,第3卷k本時所需的最少金錢,那麼有:
(9) 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,j-1,k-1)
s7 = (60 + 60 + 60) * 0.85 +MinMoney(i-1,j-1,k-1)
實現程式如下:(未完待續)