骰子游戲 python 實現

1.扔三顆骰子,求點數之和最大值出現的概率?

思想:三顆骰子的和數取值範圍在[3,18],越靠近兩邊出現的概率越小,點數最大的應該在中間,以下計算9,10,11,12的概率:

* * 首先計算出現9的概率:爲了避免重複和遺漏,將點數和爲9分成兩種情況:
(1)三個骰子點數都不相同:(1,2,6),(1,3,5),(2,3,4)
(2)可以允許存在相同的點數:(2,2,5),(3,3,3),(4,4,1)。
全不相同時對三個點數全排列,因此(1,2,6)排列共有3!= 6 種情況,存在相同點數時將不同的那個元素提出來利用插空法,所以(2,2,5)排列有3種,總的概率
P = (3! * 3 + 3* 2 + 1)/6*6*6 = 25/216.
* *  點數和爲10時,可以分爲:(1)(1,3,6),(1,4,5),(2,3,5);(2)(2,2,6),(3,3,4),(4,4,2)。
P = (3! * 3 + 3 * 3)/6*6*6 = 27/216
* * 點數和爲11時,也分爲兩種情況:(1)(1,4,6),(2,3,6),(2,4,5); (2)(3,3,5),(4,4,3),(5,5,1)
P = (3! * 3 + 3 * 3)/6*6*6 = 27/216
* * 點數和爲12,(1)(1,5,6),(2,4,6),(3,4,5); (2)(3,3,6),(4,4,4),(5,5,2)
P = 25/216
所以點數和最大的可能是10或者11.
 

2. 網易遊戲的骰子游戲 

題目描述:


小易參加了一個骰子游戲,這個遊戲需要同時投擲n個骰子,每個骰子都是一個印有數字1~6的均勻正方體。
小易同時投擲出這n個骰子,如果這n個骰子向上面的數字之和大於等於x,小易就會獲得遊戲獎勵。
小易想讓你幫他算算他獲得獎勵的概率有多大。

輸入描述:

輸入包括兩個正整數n和x(1 ≤ n < 25, 1 ≤ x < 150),分別表示骰子的個數和可以獲得獎勵的最小數字和。

輸出描述:

輸出小易可以獲得獎勵的概率。
如果概率爲1,輸出1,如果概率爲0,輸出0,其他以最簡分數(x/y)的形式輸出。


解題思路:


可能出現的值的範圍爲:n~6*n

1、回溯法

回溯法枚舉n個骰子(6面)的全排列,然後計算每一次排列所有值的和,並統計該和的出現的次數,除以6^n(全排列的全部可能性),即爲概率。

2. DP 動態規劃

假設f(m,s)表示投第m個骰子時,點數之和s出現的次數,投第m個骰子時的點數之和只與投第m-1個骰子時有關。
遞歸方程:f(m,s)=f(m-1,s-1)+f(m-1,s-2)+f(m-1,s-3)+f(m-1,s-4)+f(m-1,s-5)+f(m-1,s-6),表示本輪點數和爲s出現次數等於上一輪點數和爲s-1,s-2,s-3,s-4,s-5,s-6出現的次數之和。
初始條件:第一輪的f(1),f(2),f(3),f(4),f(5),f(6)均等於1.
需要求的是:f(n , n)、 f(n, n+1)....f(n, 6*n)
下面的代碼: 是用了空間壓縮的dp,並且一定要注意 dp數組應該是long long,因爲全部排列的6^n 很大,用int會溢

def probility(n, x):
    dp = [[0]*6*n+[0] for _ in range(n)]
    for i in range(1,7):
        dp[0][i] = 1
    for i in range(1,n):
        for j in range(1,(i+1)*6+1):
            for k in range(1,min(7, j+1)):
                dp[i][j] += dp[i-1][j-k]
    res = 0
    for i in range(x,n*6+1):
        res += dp[-1][i]
    return res
def gcd(a, b):
    while b:
        a, b = b, a%b
    return a
n, x = map(int, input().split())
if x <= n:
    print(1)
elif x > n*6:
    print(0)
else:
    pro = probility(n, x)
    cum = 6**n
    g = gcd(pro, cum)
    print(str(pro//g)+'/'+str(cum//g))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章