LeetCode第184场周赛:5383. 给 N x 3 网格图涂色的方案数(简单DP)

你有一个 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

思路:定义dp[i][j][k][h]:表示第i行状态为(j, k, h)时的方案数,其中j,k,h只能取0,1,2分别表示三种颜色。

进一步优化:因为第i行只和第i-1行有关,因此我们可以将dp数组的第一维变为2(PS:我懒得弄了)。

class Solution {
    public int numOfWays(int n) {
    	
    	int mod=1000000007;
    	long[][][][] dp=new long[n+1][3][3][3];
    	
    	for(int i=0;i<3;i++)
    		for(int j=0;j<3;j++)
    			for(int k=0;k<3;k++) {
    				if(i==j || j==k) continue;
    				dp[1][i][j][k]=1;
    			}
    	
    	for(int i=2;i<=n;i++) {
    		for(int ii=0;ii<3;ii++)
    			for(int jj=0;jj<3;jj++)
    				for(int kk=0;kk<3;kk++) {
    					if(ii==jj || jj==kk) continue;
    					for(int iii=0;iii<3;iii++)
    						for(int jjj=0;jjj<3;jjj++)
    							for(int kkk=0;kkk<3;kkk++) {
    								if(iii==jjj || jjj==kkk)
    									continue;
    								if(iii==ii || jjj==jj || kkk==kk)
    									continue;
    								dp[i][ii][jj][kk]=(dp[i][ii][jj][kk]+dp[i-1][iii][jjj][kkk])%mod;
    							}
    				}
    	}
    	long ans=0;
    	for(int i=0;i<3;i++)
    		for(int j=0;j<3;j++)
    			for(int k=0;k<3;k++) {
    				if(i==j || j==k) continue;
    				ans=(ans+dp[n][i][j][k])%mod;
    			}
    	
    	return (int)ans;
    }
}
原创文章 1111 获赞 194 访问量 25万+

猜你喜欢

转载自blog.csdn.net/haut_ykc/article/details/105467245
今日推荐