Swift學習 n個骰子的總和

2021-07-02 07:02:39 字數 2116 閱讀 3597

參考自:

(作者原話)題目:把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...