LeetCode-Python-1155. 掷骰子的N种方法

  • Post author:
  • Post category:python


这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, …, f。

我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和。

如果需要掷出的总点数为 target,请你计算出有多少种不同的组合情况(所有的组合情况总共有 f^d 种),模 10^9 + 7 后返回。

示例 1:

输入:d = 1, f = 6, target = 3

输出:1

示例 2:

输入:d = 2, f = 6, target = 7

输出:6

示例 3:

输入:d = 2, f = 5, target = 10

输出:1

示例 4:

输入:d = 1, f = 2, target = 3

输出:0

示例 5:

输入:d = 30, f = 30, target = 500

输出:222616187

提示:

1 <= d, f <= 30

1 <= target <= 1000

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/number-of-dice-rolls-with-target-sum

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

十位数级别的数据规模,暗示回溯。

题目问的是有多少种不同的组合,明示回溯。

所以本题用回溯解题:

因为数据规模有点大,所以要用记忆化搜索的方法,把每个子问题的解记录下来,

方便下一次处理相同的子问题的时候可以直接读取结果,而不用往下搜索。

class Solution(object):
    def numRollsToTarget(self, d, f, target):
        """
        :type d: int
        :type f: int
        :type target: int
        :rtype: int
        """
        record = dict()
        def backtrack(dice, face, t):
            if (dice, face, t) in record: #如果已经知道当前问题的解
                return record[(dice, face, t)] #直接读取即可
            
            if dice == 0: #当没有骰子的时候,判断一下是不是刚好找到target
                return 1 if t == 0 else 0
            
            if t < 0 or dice <= 0: #无效的时候没有解,所以返回0
                return 0
            tmp = 0 #tmp用于记录当前问题有多少个解
            for i in range(1, face + 1): #尝试所有的组合
                tmp += backtrack(dice - 1, face, t - i) 
                
            record[(dice, face, t)] = tmp #把解存起来,方便以后用
            return tmp
        
        backtrack(d, f, target)
        return max(record.values()) % (10 ** 9 + 7) #最大的解就是母问题的解



版权声明:本文为qq_32424059原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。