(1)李白喝酒
https://segmentfault.com/q/1010000000443863
本貼是對上述地址的問題思考。
問題:
李白街上走,提壺去買酒,遇店加一倍,見花喝一斗。途中遇5次店,見10次花,壺中原有2斗酒,最后剛好遇見花,剛好喝完酒,求可能的解。
分析:從兩個角度去分析,一個是人的角度,另一個是計算機角度。
人的角度:把問題抽象成數學問題求解,確定一些關系。
1.共見花10次=-10(斗酒),原有2斗酒=2,即增加的酒是-(-10+2)=8(斗酒)
問題變成了在五次中增加8斗酒的可能解(遇店=加酒=1,見花=減酒=0,即對5個1和10個0進行排列組合,最后一次是0。由于見花不存在順序的區別,所以只需要把遇店的可能情況排出來再填入見花即可,所以五次中增加8斗酒的可能解就是最終整個問題的可能解數)
2.增加的酒數要滿足5次一共加8斗,注定了增加的酒數不能大于4(五次中每次都加1斗酒是最少的,還剩下3斗,全部加到其中一次就是4斗,即一次最大只能加4斗)。
綜合上述兩點,我們可以有:
11222/11132/11114這三種可能,
那么這三種可能是否有不成立的呢(下面說的“基數”指翻倍前的酒數)?
對于11114:
要想增加4斗酒,就必須有基數4去翻倍。基數是4的可能情況有:
A.原先有2斗酒,遇店后變成4斗
此時必須有24,而11114中沒有2,所以不可能。
B.原先有n(n≥5)斗酒,遇花后變成4斗再遇店
原先有2斗,已經增加了至少3斗酒(n-2≥3),還要增加4斗,則一共增加了3+4=7斗,也就是說,要遇店4次加7斗酒(還有一次加1斗才滿足5次加8斗的條件),其中有一次是加4斗的,也就是遇店3次加3斗,而這是不可能的(相當于1次加1斗,而1次加1斗意味著基數是1,那么又怎么能有n斗酒出現呢?n可是大于等于5的!)。綜上,11114的情況是不可能的。
(其實看到1111就知道不可能了,增加1斗酒,基數必須是1,四個基數都是1,后面不可能基數變成4出現增加1斗酒的情況。這是我后來才發現的....)
11222是可能的,保持基數是2和1是很容易的事情。
11132,要想增加3斗酒,就必須有基數3去翻倍,所以不可能是連續三個1在3前面,必須是23連著才行。
至此,我們知道了可能的情況是11222,32111.利用高中的排列組合,我們可以有:
11222的可能情況是C25,32111的可能情況是C14,加起來一共14種可能。
計算機角度:函數與條件
設J=酒,D=遇店剩余次數,H=見花剩余次數
初始條件可列:
J=2,D=5,H=10;最后一次是H;J=0,D=0,H=0
其它條件可列:
F(J,H,D)
F(0,H≠0,D≠0),false;F(J≠0,0,D≠0),false;(不能只有J=H=D=0才true,這樣就是暴力遞歸而非用剪枝條件優化算法。什么是暴力遞歸和剪枝條件看開頭的網址)
F(J,H(J>H),D),false;F(J,H(J·2^D<H),D),false
然后是函數關系:
H=H-1時,F=F(J-1,H,D);D=D-1時,F=F(2J,H,D)
用if循環來遞歸就可以得出解了。詳細的代碼在開頭的網址里有。(有空我會用C++實現,然后補充進這個帖子)
回顧上面兩個角度,我發現所謂算法,和人的角度本質上是一樣的:人在思考的時候往往一開始也是用窮舉的方法去思考,只不過我們沒有那么死板,我們會用“剪枝”(開頭的文章地址中提到的一個詞)去把一些不對的方法給刪去(比如上文我通過一系列的演算把11114這條去掉了)。而計算機的算法就是在繼續人“剪枝”后的窮舉。
以上所有,就是我在李白喝酒問題中學到的思維與方法。
wuduojia
總結
- 上一篇: 请验证实例名称是否正确并且 sql se
- 下一篇: 学习笔记153—matlab中小数如何取