把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
示例 1:
输入: 1
输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
————————————————
解题思路一:使用递归,要求n个骰子的点数和,可以先求n-1棵骰子的点数和,通过递归可以计算每种点数和的数量,然后存在列表中。
class Solution:
def twoSum(self, n: int) -> List[float]:
if n<1:
return []
max_sum = n*6 # n个骰子的最大点数
prob = [0 for _ in range(max_sum-n+1)] # n个骰子的所有可能点数
def probablity(n1,prob): # 计算n1个骰子的所有情况
for i in range(1,7):
probablities(n1,n2,i,prob) # n1是骰子个数,n2是当前是第几个骰子,i是当前骰子值之和,prob用于存储不同点数的个数
def probablities(n1,n2,sums,prob): # 递归函数
if n2==1: # 停止递归条件
prob[sums-n1]+=1 # 对应点数位置加1,减去n1的目的是因为n1前的值不可能取到
else:
for i in range(1,7):
probablities(n1,n2-1,sums+i,prob)
probablity(n,prob) # 获得所有点数的个数情况
total = 6**n # 一共会有多少种组合
num = [] # 记录不同点数的概率
for n in prob:
num.append(n/total)
return num
解题思路2:在下一轮循环中,我们加上一个新的骰子,此时和为n的骰子出现的次数应该等于上一轮循环中骰子点数和为n-1、n-2、n-3、n-4、n-5与n-6的次数的总和,所以我们使用另一个数组的第n个数字设为前一个数组对应的第n-1、n-2、n-3、n-4、n-5与n-6个数字之和。
其Python代码如下:
class Solution:
def twoSum(self, n: int) -> List[float]:
max_num = n*6 # n个骰子的最大值
nums = [[0 for _ in range(max_num)] for _ in range(n)] # 初始化骰子状态,用n个数组
for i in range(0,6): # 初始化一个骰子的状态
nums[0][i] = 1
for i in range(1,n): # 从第二个骰子开始更新状态
for j in range(i,(i+1)*6): # 第i个骰子的取值范围为i到(i+1)*6
for k in range(1,7): # 取对应骰子位置的前6个值
if j-k<0: # 如果前六个值的索引小于0
break # 跳出循环
nums[i][j]+=nums[i-1][j-k]
total = 6**n # 计算每种值的概率
pro = []
for nn in nums[n-1][n-1:]:
pro.append(nn/total)
return pro