zoukankan      html  css  js  c++  java
  • 5811. 用三种不同颜色为网格涂色 力扣周赛(Hard) dfs+dp

    题目描述:

    给你两个整数 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/

    题解:https://leetcode-cn.com/problems/painting-a-grid-with-three-different-colors/solution/fei-chang-zhi-guan-de-dong-tai-gui-hua-b-f34f/

    首先,因为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;
        }
    };
  • 相关阅读:
    架构与模式11
    Unix/Linux命令
    Winform的Excel表格
    B/S结构一机多屏实现
    Effective C++函数参数传递方式
    Django & Tornado
    ThoughtWorks读书路线图
    善用泛型 委托
    SQL 关于with cube ,with rollup 和 grouping
    测试工程师实习笔试题
  • 原文地址:https://www.cnblogs.com/stepping/p/14998775.html
Copyright © 2011-2022 走看看