• 【Leetcode】1444. Number of Ways of Cutting a Pizza


    题目地址:

    https://leetcode.com/problems/number-of-ways-of-cutting-a-pizza/

    给定一个 m × n m\times n m×n字符矩阵,只含'A''.'。要求将其切成 k k k块(即切 k − 1 k-1 k1刀)。每次可以横着切一刀或者竖着切一刀,要求切出的那一块必须含'A'。问有多少种不同的切分方式。

    思路是记忆化搜索。设 f [ x ] [ y ] [ c ] f[x][y][c] f[x][y][c]是从 ( x , y ) (x, y) (x,y) ( m − 1 , n − 1 ) (m-1,n-1) (m1,n1)这一部分的不同切分方式。那么我们就是要求 f [ 0 ] [ 0 ] [ k − 1 ] f[0][0][k-1] f[0][0][k1]。可以直接枚举第一刀是怎么切的,然后递归处理即可。为了快速判断某个子矩阵是否含'A',我们可以用一个前缀和数组预处理一下。代码如下:

    class Solution {
     public:
      vector<vector<int>> pre;
      int MOD = 1e9 + 7;
      int ways(vector<string>& ps, int k) {
        int m = ps.size(), n = ps[0].size();
        pre = vector<vector<int>>(m + 1, vector<int>(n + 1, 0));
        for (int i = 1; i <= m; i++)
          for (int j = 1; j <= n; j++)
            pre[i][j] = (ps[i - 1][j - 1] == 'A' ? 1 : 0) + pre[i - 1][j] +
                        pre[i][j - 1] - pre[i - 1][j - 1];
        vector<vector<vector<int>>> f(m, vector<vector<int>>(n, vector<int>(k, -1)));
        return dfs(0, 0, m, n, k - 1, f);
      }
    
      int dfs(int x, int y, int m, int n, int k, vector<vector<vector<int>>>& f) {
        if (x == m || y == n) return 0;
        if (~f[x][y][k]) return f[x][y][k];
        if (!k) return f[x][y][k] = check(x, y, m - 1, n - 1) ? 1 : 0;
        int res = 0;
        for (int i = x; i < m; i++)
          if (check(x, y, i, n - 1))
            res = (res + dfs(i + 1, y, m, n, k - 1, f)) % MOD;
        for (int j = y; j < n; j++)
          if (check(x, y, m - 1, j))
            res = (res + dfs(x, j + 1, m, n, k - 1, f)) % MOD;
    
        return f[x][y][k] = res;
      }
    
      bool check(int x1, int y1, int x2, int y2) {
        return pre[x2 + 1][y2 + 1] - pre[x1][y2 + 1] - pre[x2 + 1][y1] +
                   pre[x1][y1] > 0;
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    时空复杂度 O ( m n k ) O(mnk) O(mnk)

  • 相关阅读:
    20221031
    打印机修复脚本
    索尼 toio™ 应用创意开发征文|探索创新的玩乐世界——索尼 toio™
    【Ingress】
    Nginx 日志配置
    如何在Linux使用Docker部署Nexus容器并实现公网访问本地仓库【内网穿透】
    运动App如何实现端侧后台保活,让运动记录更完整?
    教师生成教案的提示词
    Oracle与Mysql语法区别
    范德蒙德卷积 学习笔记
  • 原文地址:https://blog.csdn.net/qq_46105170/article/details/128010731