參考自:
(作者原話)題目:把n個骰子仍在地上,所有骰子的點數和為s。輸入n,列印s所有可能取值的概率。
分析1:容易知道,有n個骰子的話,s的最小取值為n(全為1),最大取值為6n(全為6)。
如果只有1個骰子,那麼很簡單,s取1,2,3,4,5,6的情況數均為1,概率為1/6;設想有n個骰子,出現和為s,我們可以這樣考慮,如果第乙個骰子有6中情況,取1,2,3,4,5,6;那麼剩下的n-1個骰子的和則分別取s-1,s-2, s-3,s-4,s-5, s-6,我們將所有這些情況相加,就可以得出總的情況數。看出了嗎?親,這是什麼問題?對了,還是遞迴問題,根據以上分析我們不難寫出如下的遞迴公式:
(作者原話)對公式的說明:(1)f(s,n)表示,有n個骰子,出現和為s的情況總數;(2)對於公式第二行的解釋;如果有乙個骰子,那麼點數為8或者0的情況數,我們記為0,這樣是為了在計算遞迴時更為方便所作的處理;例如有公式可知f(8,2)=f(7,1)+f(6,1)+f(5,1)+f(4,1)+f(3,1)+f(2,1),如果我們規定了f(7,1)=0那麼計算會方便很多。
有了上面的分析,我們可以寫出如下**:
var dicemaxvalue:int =
6//計算給定dicenumber個骰子,出現和為dicetotalsum的所有可能情況的總數
//int fun(int dicetotalsum, int dicenumber)
func mainfun(dicetotalsum:int, dicenumber:int)->int
//骰子數等於1,如果超出1~6範圍便錯誤,未超出則是1
if dicenumber ==
1 else
}//n>1,採用遞迴
if dicenumber >
1 return
sum }
return0}
//給定number個骰子,列印出現各種情況的概率
func printsumprobabilityofdice1(number:int)
var maxsum:int = number * dicemaxvalue
var pprobability:array
=array()
for index in number...maxsum
var total:int = int(pow(float(dicemaxvalue), float(number)))
for count in
0...maxsum-number
}
(作者原話)分析2:和演算法2中求解斐波那契數列的方法類似,遞迴的效率太差,我們可以正向來求解,假設我們有乙個陣列表示k-1個骰子中各點數的情況,令第s個分量表示和為s時情況總數,那麼當有k個骰子是,其和為s時的情況總數,就是表示k-1骰子的陣列中的s-1,s-2,s-3,s-4,s-5,s-6的和(分別令引入的第k個骰子的值分別取1,2,3,4,5,6即可,其實和分析1的思路差不太多)。根據這個思想,我們可以用兩個陣列交替表示陣列k-1和陣列k,於是我們有如下的**:
func printsumprobabilityofdice2(number:int)
//骰子數k從2到n迴圈;對於每一k,s取值為[k,6k],對於每乙個s計算前乙個陣列
//的s-1,s-2,s-3,s-4,s-5,s-6;因為前乙個陣列的最小值為k-1,因為因而有s-j>=k-1;
for k in
2...number
}flag = 1 - flag
}var total:double = pow(double(dicemaxvalue), double(number))
for ss in number...number*dicemaxvalue
}
(作者原話)最後分析:我們看到和【演算法02】中提到的一樣,雖然該演算法的時間複雜度提高了很多,但是動態建立了兩個陣列,而且每乙個的陣列長度都沒分析1中的長度多了乙個n,因而還是以空間換時間的思想。好了,這個演算法就到這,祝各位愉快!
何海濤部落格:
wikipedia:
n個骰子的點數
把n個骰子扔在地上,所有骰子朝上的一面的點數之和為s。輸入n,列印出s的所有可能的值和出現的概率。1 基於迴圈求骰子點數 2int g maxvalue 6 骰子的點數個數 3void printprobability int number number 為骰子個數49 int pprobabili...
n個骰子的點數
題目 把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能的值出現的概率。方法一 遞迴 思路 設n個骰子某次投擲點數和為s的出現次數是f n,s 那麼,f n,s 等於n 1個骰子投擲的點數和為s 1 s 2 s 3 s 4 s 5 s 6時的次數的總和 f n s f n...
n個骰子的點數
題目 把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能的值出現的概率。方法一 遞迴 思路 設n個骰子某次投擲點數和為s的出現次數是f n,s 那麼,f n,s 等於n 1個骰子投擲的點數和為s 1 s 2 s 3 s 4 s 5 s 6時的次數的總和 f n s f n...