[LeetCode in Python] 5383 (H) number of ways to paint n x 3 grid 给 N x 3 网格图涂色的方案数

题目:

https://leetcode-cn.com/problems/number-of-ways-to-paint-n-x-3-grid/

你有一个 n x 3的网格图 grid,你需要用 红,黄,绿三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直边的格子颜色不同)。
给你网格图的行数 n。
请你返回给grid涂色的方案数。由于答案可能会非常大,请你返回答案对10^9 + 7取余的结果。

示例 1:

输入:n = 1
输出:12
解释:总共有 12 种可行的方法:

示例 2:

输入:n = 2
输出:54

示例 3:

输入:n = 3
输出:246

示例 4:

输入:n = 7
输出:106494

示例 5:

输入:n = 5000
输出:30228214

提示:

n == grid.length
grid[i].length == 3
1 <= n <= 5000

解题思路

  • 使用数学方法当然是最销魂的,咱还是用简单粗暴的方法吧。
  • 显而易见,只要确定了相邻两行的转换关系,剩下的就是迭代了。
  • 手写第一行的模式,只有12个,多乎哉?不多也。
  • 然后穷举遍历,得到这12个模式对应的全部可能的下一行模式,存为next字典备用。
  • 将第一行的模式存为prev字典,key是模式,value初始化为1,表示第一行每种模式都只有1个。
  • 然后就是从第2行开始遍历到最后一行。
  • 在每一行的开始,先存一个字典curr,存储每种模式出现的次数。
  • 然后重点来了!
  • 遍历prev的key,从next[key]中取得全部可能的模式,更新curr[next[key]]。
  • 注意这里更新的时候,需要每次累加prev[key]。
  • 在每行结束的时候,将curr的内容存入prev。
  • 程序最后将prev的value求和再取模,完事儿。

代码

class Solution:
    def numOfWays(self, n: int) -> int:
        pattern = [
          'RGB', 'RBG', 'RGR',
          'RBR', 'GBR', 'GRB',
          'GRG', 'GBG', 'BRG',
          'BGR', 'BRB', 'BGB'
        ]

        # - construct transfer dict
        # - to handle adjacent rows
        next = {}
        for p1 in pattern:
          next[p1] = []
          for p2 in pattern:
            is_ok = True
            for i in range(3):
              if p1[i] == p2[i]:
                is_ok = False
                break
            if is_ok:
              next[p1].append(p2)
        
        # - first row
        prev = {p:1 for p in pattern}
        
        # - from second row
        for i in range(n-1):
            # - d is temp dict for current row
            curr = {p:0 for p in pattern}
            
            # - accumulate
            for k,v in prev.items():
                for x in next[k]:
                    curr[x] += v
            
            # - update previous row
            prev = copy.copy(curr)
            
        return sum(prev.values()) % (10**9 + 7)
posted @ 2020-04-12 12:37  ET民工[源自火星]  阅读(293)  评论(0编辑  收藏  举报