LeetCode Biweekly Contest No. 81 (4/4)

2318. Number of Distinct Roll Sequences

题目描述:

You are given an integer n. You roll a fair 6-sided dice n times. Determine the total number of distinct sequences of rolls possible such that the following conditions are satisfied:

  1. The greatest common divisor of any adjacent values in the sequence is equal to 1.
  2. There is at least a gap of 2 rolls between equal valued rolls. More formally, if the value of the ith roll is equal to the value of the jth roll, then abs(i - j) > 2.

Return the total number of distinct sequences possible. Since the answer may be very large, return it modulo 109 + 7.

Two sequences are considered distinct if at least one element is different.

Example 1:

Input: n = 4
Output: 184
Explanation: Some of the possible sequences are (1, 2, 3, 4), (6, 1, 2, 3), (1, 2, 3, 1), etc.
Some invalid sequences are (1, 2, 1, 3), (1, 2, 3, 6).
(1, 2, 1, 3) is invalid since the first and third roll have an equal value and abs(1 - 3) = 2 (i and j are 1-indexed).
(1, 2, 3, 6) is invalid since the greatest common divisor of 3 and 6 = 3.
There are a total of 184 distinct sequences possible, so we return 184.

Example 2:

Input: n = 2
Output: 22
Explanation: Some of the possible sequences are (1, 2), (2, 1), (3, 2).
Some invalid sequences are (3, 6), (2, 4) since the greatest common divisor is not equal to 1.
There are a total of 22 distinct sequences possible, so we return 22.

Constraints:

  • 1 <= n <= 10^4

解题思路:

这个题,看条件,要求相邻两个骰子的点数互质,且两个相同的面要间隔大于2个。

这两个条件一打眼应该就是用动态规划+状态机来做。

用res<p,q>来存放当前的面为p,前一个面为q的可能性的个数,假设我们已知当前面为x、前一个面为y的组合个数,那下一个面z必须要满足:(x,z)=1,和y≠z。并且res<y,z>=sum(res<x,y> for x in y.prev)。

我们只需要用一个状态机来解决每个y前一个面的点数的可能性即可。

1: [2, 3, 4, 5, 6],
2: [1, 3, 5],
3: [1, 2, 4, 5],
4: [1, 3, 5],
5: [1, 2, 3, 4, 6],
6: [1, 5]

于是:

class Solution:
    def distinctSequences(self, n: int) -> int:
        if n == 1: return 6
        res = collections.defaultdict(int)
        mod = 10 ** 9 + 7
        p_next = {
            1: [2, 3, 4, 5, 6],
            2: [1, 3, 5],
            3: [1, 2, 4, 5],
            4: [1, 3, 5],
            5: [1, 2, 3, 4, 6],
            6: [1, 5]
        }
        for i in range(6):
            for j in p_next[i + 1]:
                res[(j, i + 1)] = 1
        for i in range(2, n):
            m = collections.defaultdict(int)
            for j in range(6):
                for k in p_next[j + 1]:
                    cur = 0
                    for l in p_next[k]:
                        if j + 1 != l:
                            cur += res[(l, k)] % mod
                    m[(k, j + 1)] = cur
            res = m
        return sum(v for k, v in res.items()) % mod

时间复杂度:O(N*6*6*6),用状态机将后面的6优化为小一些。

额外空间复杂度:O(36)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值