【面试题60 n个骰子的点数】
面试题60:n个骰子的点数:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
思路:动态规划。可以考虑用一个二维数组存储 dp 状态,行 i
表示当前已经掷了 i
个骰子,列 j
表示骰子的点数和,dp[i][j]
表示当前有 i
个骰子,有 dp[i][j]
种组合方式得到点数和 j
。对于 n
个骰子,掷法组合是 6 n 6^n 6n 种,所以最后返回的结果就是 dp 数组最后一行(n个骰子)不为 0 的结果除以 6 n 6^n 6n,即概率值。
dp[i][j]
表示当前有 i
个骰子,有 dp[i][j]
种组合方式得到点数和 j
i
个骰子,要组合出点数 j
,可以看作是 i-1
个骰子再加上一个点数(1~6),即 dp[i][j]
可以由 dp[i-1][j-1]
、dp[i-1][j-2]
…、dp[i-1][j-6]
的累加和得来。dp[i][j] += dp[i-1][j-cur]
,其中 cur 的范围是 1 ~ 6i
等于 1 时,即只有 1 个骰子,j = 1 ~ 6
的掷法都是 1class Solution:
def twoSum(self, n: int):
dp = [[0]*(6*n+1) for _ in range(n+1)]
res = []
for i in range(1,7):
dp[1][i] = 1
for i in range(1, n+1): # 骰子个数
for j in range(i, 6*n+1): # 点数
for cur in range(1,7):
dp[i][j] += dp[i-1][j-cur]
sum = pow(6, n)
for i in range(6*n+1):
if dp[n][i] != 0:
res.append(dp[n][i] / sum)
return res