[刷題] n 個色子的點數
阿新 • • 發佈:2018-12-11
題目:
把n個骰子扔在地上,所有骰子朝上的一面的點數之和為s.輸入n,打印出s的所有可能的值出現的概率.
思路:
動態規劃:
- 設定兩個陣列,用陣列中的第n個數表示骰子點數和為n的次數;
- 第k次投擲骰子的數可能為1~6中的任意一個數,如果我們假設第k次投擲骰子最終所有的和為n,那麼和為n的次數就為前一次投擲(第k-1次投擲)和為n-1、n-2、n-3、n-4、n-5、n-6的次數的總和。
- 同時知道第1次投擲和為1,2,3,4,5,6的次數均為1;同時第k次投擲時,和為0、1、2…k-1將不會存在;
- 我們使用兩個陣列來交替進行,一個用來儲存上一次投擲的和的次數,另一個以對方為基礎用來計算當前投擲和的次數。每次用flag來交替。
def probability(number,maxValue):
if number < 1:
return
p = [[0 for i in range(maxValue * number + 1)] for i in range(2)]
flag = 0
for i in range(1,maxValue+1):
p[flag][i] = 1
#第一次投色子, 更新1到6
for k in range(2,number+1): #k次投色子
for i in range(k):
p[1-flag][i] = 0
#第k次 投色子時, 和為0~k-1的值都是不可能的.更新為0
for i in range(k,maxValue*k+1):
p[1-flag][i] = 0
j = 1 # F(n|k) = f(n-1|k-1) + f(n-2 |k-1) + f(n-3|k-1) + f(n-4|k-1) ... + f(n-6|k-1) n ~ (k, maxValue*k)
while j <= i and j <= maxValue:
p[1-flag][i] += p[flag][i-j]
j += 1
flag = 1 - flag