# 1931. Painting a Grid With Three Different Colors
###### tags: `Leetcode` `Hard` `Dynamic Programming`
Link: https://leetcode.com/problems/painting-a-grid-with-three-different-colors/
## 思路
和[1349. Maximum Students Taking Exam](https://hackmd.io/pIRFwFXgQGWTbTNDPwrYDg), [1411. Number of Ways to Paint N × 3 Grid](https://hackmd.io/AKffexhVRtGqAo1_PAqr2Q)很像
但是区别在于之前是每一行写成一个mask表示三个格子用了什么颜色
但现在由于行数通常比列数小 (列数可以到1000,而行数最大到5) 所以我们为了节省空间把每一列写成一个mask
还有一个变动是我们提前存下了所有有可能的mask(相邻两个颜色不一样)
这样就不用遍历所有$3^n$个mask
否则就会TLE
## Code
```java=
class Solution {
public int colorTheGrid(int m, int n) {
if(m<n) return colorTheGrid(n,m);
int mod = 1000000007;
List<Integer> candidate = new ArrayList<>();
for(int i=0; i<Math.pow(3,n); i++){
if(selfCheck(i,n)) candidate.add(i);
}
long[] dp = new long[candidate.size()];
Arrays.fill(dp,1);
for(int i=1; i<m; i++){
long[] temp = dp.clone();
for(int j=0; j<candidate.size(); j++){
int mask = candidate.get(j);
dp[j] = 0;
for(int k=0; k<candidate.size(); k++){
int prevMask = candidate.get(k);
if(checkDiffRow(mask,prevMask,n)){
dp[j] = (temp[k]+dp[j])%mod;
}
}
}
}
long ans = 0;
for(int i=0; i<candidate.size(); i++){
ans = (ans+dp[i])%mod;
}
return (int)ans;
}
private boolean selfCheck(int mask, int n){
int prev = -1;
for(int i=0; i<n; i++){
int curr = mask%3;
if(prev==curr) return false;
prev = curr;
mask /= 3;
}
return true;
}
private boolean checkDiffRow(int m1, int m2, int n){
for(int i=0; i<n; i++){
if(m1%3==m2%3) return false;
m1/=3;
m2/=3;
}
return true;
}
}
```