Python top-down DP
We represent cells with an integer, so the row "rgb" -> (0,1,2)  \n\nThis is the core dp function, counting the number of valid colourings of a mxn grid with th
We represent cells with an integer, so the row "rgb" -> `(0,1,2)`  \n\nThis is the core dp function, counting the number of valid colourings of a `mxn` grid with the constraint that the topmost row must be able to be placed below a row `prev`\n\n```\n@lru_cache(None) \ndef ans(self, n, prev):\n\tif n == 0: return 1\n\tret = 0\n\tfor s in self.states: \n\t\tif ok2(s, prev):\n\t\t\tret += self.ans(n-1,s)\n\t\t\tret %= MODULUS\n\treturn ret % MODULUS\n```\n\nWe have the functions `ok1` and `ok2` to compute when a row is valid, and when two valid rows can be placed adjacently\n\n```\ndef ok1(self, seq):\n\tfor i in range(self.m-1):\n\t\tif seq[i] == seq[i+1]: return False\n\treturn True\n\t\t\ndef ok2(s1, s2):\n    for i in range(len(s1)):\n        if s1[i] == s2[i]: return False\n    return True\n```\n\nThe final solution prepopulates the set of valid rows, `self.state`\n\n```\nclass Solution:    \n    def colorTheGrid(self, m: int, n: int) -> int:\n        self.m = m\n        self.states = []\n\n        for seq in itertools.product([0,1,2], repeat=m):\n            if self.ok1(seq):\n                self.states += [seq]\n            \n        return self.ans(n, (-1,)*m)\n```
[]