题目描述:
给你两个整数 m
和 n
。构造一个 m x n
的网格,其中每个单元格最开始是白色。请你用 红、绿、蓝 三种颜色为每个单元格涂色。所有单元格都需要被涂色。
涂色方案需要满足:不存在相邻两个单元格颜色相同的情况 。返回网格涂色的方法数。因为答案可能非常大, 返回 对 109 + 7
取余 的结果。
示例 1:
输入:m = 1, n = 1 输出:3 解释:如上图所示,存在三种可能的涂色方案。
题源:https://leetcode-cn.com/problems/painting-a-grid-with-three-different-colors/
首先,因为m小,枚举列状态(m=1,状态数3;m=2,状态数3*2;m=3,状态数3*2*2;m=4,状态数3*2*2*2=24;m=5,状态数3*2*2*2*2=48),其实数字很小的
然后,dp[i][j]表示第i列为j状态时,方法数为多少,0<j<状态数-1,判断dp[i-1][ 0 ~(状态数-1)]能否转移,想法直观简单
注意点:数组要memset否则自己这里能过,但是测试会答案出错!!!!
代码:
class Solution { public: vector<vector<int>> states; vector<int> substate; int M; void getstates(int k) { if(k==M+1) { states.push_back(substate); return; } for(int i=0;i<3;i++) { if(substate.size()==0) substate.push_back(i); else if (substate.back()!=i) substate.push_back(i); else continue; getstates(k+1); substate.pop_back(); } return; } bool isok(int i,int j) { for(int k=0;k<M;k++) if (states[i][k]==states[j][k]) return false; return true; } int colorTheGrid(int m, int n) { M=m; getstates(1); //利用DFS,得到所有状态 int s=states.size(); long long dp[1005][55]; long long mod=1e9+7; memset(dp,0,sizeof(dp)); //必须有,否则会出错 for(int i=0;i<s;i++) dp[1][i]=1; for(int i=2;i<=n;i++) { for(int j=0;j<s;j++) //枚举i类状态 for(int k=0;k<s;k++) //枚举i-1列状态 if (isok(j,k)) //两种状态能不能相邻 dp[i][j]=(dp[i][j]+dp[i-1][k])%mod; } long long res=0; for(int i=0;i<s;i++) res=(res+dp[n][i])%mod; return res; } };