n個篩子的點數

2021-07-05 03:35:25 字數 1907 閱讀 6794

題目:把

n個骰子扔在地上,所有骰子朝上一面的點數之和為

s。輸入

n,列印出

s的所有可能的值出現的概率。

分析:玩過麻將的都知道,骰子一共

6個面,每個面上都有乙個點數,對應的數字是1到

6之間的乙個數字。所以,

n個骰子的點數和的最小值為

n,最大值為

6n。因此,乙個直觀的思路就是定義乙個長度為

6n-n

的陣列,和為

s的點數出現的次數儲存到陣列第

s-n個元素裡。另外,我們還知道

n個骰子的所有點數的排列數6

^n。一旦我們統計出每一點數出現的次數之後,因此只要把每一點數出現的次數除以6

^n,就得到了對應的概率。

該思路的關鍵就是統計每一點數出現的次數。要求出

n個骰子的點數和,我們可以先把

n個骰子分為兩堆:第一堆只有乙個,另乙個有

n-1個。單獨的那乙個有可能出現從1到

6的點數。我們需要計算從1到

6的每一種點數和剩下的

n-1個骰子來計算點數和。接下來把剩下的

n-1個骰子還是分成兩堆,第一堆只有乙個,第二堆有

n-2個。我們把上一輪那個單獨骰子的點數和這一輪單獨骰子的點數相加,再和剩下的

n-2個骰子來計算點數和。分析到這裡,我們不難發現,這是一種遞迴的思路。遞迴結束的條件就是最後只剩下乙個骰子了。

*************************=  以上文字引用自原文(劍指offer) *************************===

思路一明晰了,**應該不難寫,同樣引用原文的**:

#define max_value 6

void printp1(int n)

{ if(n<1) return ;

int maxsum=n*max_value;

int *p=new int[maxsum-n+1];

for(int i=n;i<=maxsum;i++)

p[i-n]=0;//初始化

pro(n,p);

double total=pow((double)max_value,n);

for(int i=n;i<=maxsum;i++)

{ double ratio=(double)p[i-n]/total;

cout<

動態規劃就是分階段考慮問題,給出變數,找出相鄰階段間的關係。具體定義給忘了。

1.現在變數有:骰子個數,點數和。當有k個骰子,點數和為n時,出現次數記為f(k,n)。那與k-1個骰子階段之間的關係是怎樣的?

2.當我有k-1個骰子時,再增加乙個骰子,這個骰子的點數只可能為1、2、3、4、5或6。那k個骰子得到點數和為n的情況有:

(k-1,n-1):第k個骰子投了點數1

(k-1,n-2):第k個骰子投了點數2

(k-1,n-3):第k個骰子投了點數3

....

(k-1,n-6):第k個骰子投了點數6

在k-1個骰子的基礎上,再增加乙個骰子出現點數和為n的結果只有這6種情況!

所以:f(k,n)=f(k-1,n-1)+f(k-1,n-2)+f(k-1,n-3)+f(k-1,n-4)+f(k-1,n-5)+f(k-1,n-6)

3.有1個骰子,f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。

**如下:

void printp(int n)

{ if(n<1) return;

int *ppro[2];

ppro[0]=new int[n*max_value+1];

ppro[1]=new int[n*max_value+1];

for(int i=0;i

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...