每日一道Leetcode - 剑指 Offer 60. n个骰子的点数【动态规划】

每日一道Leetcode - 剑指 Offer 60. n个骰子的点数【动态规划】_第1张图片

class Solution:
    def dicesProbability(self, n: int) -> List[float]:
        """
        分析问题:2枚骰子的情况
        第一枚可能情况:1,2,3,4,5,6 【已知情况】
        第二枚可能情况(在第一枚的基础上):1+[1-6],2+[1-6]..6+[1-6]
        如果想要在2枚骰子的情况下得到点数为4:
        那么第二枚骰子(第一枚情况,第二枚情况) = (1,3),(2,2),(3,1) 
        n-1 为 前一个骰子数的结果 j为想要的点数 i为当前骰子的点数
        再拓展一下:(n-1)枚骰子的(j-i) 的 六种情况
        """
        # 对于已知情况【即一枚骰子】每种点数出现的概率为1/6
        base = 1/6
        # 对于每个骰子,可能情况为6,12...
        dp = [[0]*(6*i+1) for i in range(n+1)]
        for i in range(1,7):
            dp[1][i] = base
        for i in range(2,n+1):
            for j in range(i,6*i+1):
                # 最小的情况一定是从i开始的,如:两颗骰子所得点数最小为2,最大为2个6的情况
                # dp[i-1]指的是上一个骰子
                # 当前骰子有6种可能即:1-6
                # 要凑够当前点数j,那么上一个骰子数就可以从j-1,j-2,..j-6中选,最小的是j-6,最大的是j-1,把这种情况相加,每种情况概率是1/6,再乘起来
                # 因为j-6可能存在越界的情况 所以用 max(0,j-6)
                dp[i][j] = sum(dp[i-1][max(0,j-6):j])*base
        # 最后返回第n个骰子的情况
        return dp[n][n:]

你可能感兴趣的:(Leetcode,算法,动态规划)