【Leetcode】1444. Number of Ways of Cutting a Pizza
admin
2024-02-11 03:26:03

题目地址:

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

给定一个m×nm\times nm×n字符矩阵,只含'A''.'。要求将其切成kkk块(即切k−1k-1k−1刀)。每次可以横着切一刀或者竖着切一刀,要求切出的那一块必须含'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)(m−1,n−1)这一部分的不同切分方式。那么我们就是要求f[0][0][k−1]f[0][0][k-1]f[0][0][k−1]。可以直接枚举第一刀是怎么切的,然后递归处理即可。为了快速判断某个子矩阵是否含'A',我们可以用一个前缀和数组预处理一下。代码如下:

class Solution {public:vector> pre;int MOD = 1e9 + 7;int ways(vector& ps, int k) {int m = ps.size(), n = ps[0].size();pre = vector>(m + 1, vector(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>> f(m, vector>(n, vector(k, -1)));return dfs(0, 0, m, n, k - 1, f);}int dfs(int x, int y, int m, int n, int k, vector>>& 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;}
};

时空复杂度O(mnk)O(mnk)O(mnk)。

相关内容

热门资讯

赤水性价比粮食酒推荐:2025... 赤水性价比粮食酒推荐:2025年酱香酒选购全攻略 一、开篇背景与市场痛点 2025年的赤水河流域酒类...
非白酒板块11月19日跌0.3... 证券之星消息,11月19日非白酒板块较上一交易日下跌0.33%,*ST椰岛领跌。当日上证指数报收于3...
以运河文化赋能产业发展|古贝春... 11月17日至19日,以“新质开新局,聚力创未来”为主题的2025年第六届中国白酒黄淮核心产区高质量...
深夜小酌的灵魂搭档:油炝脆骨,... 油炝脆骨是一道充满锅气与烟火气息的家常菜,以其爽脆的口感和浓郁的香辣风味深受许多人喜爱。这道菜的制作...
初中毕业新征程:为什么西点烘焙... 站在初中毕业的人生路口,许多女孩都在思考:哪条路能通往一个既美好又独立的未来?如果有一条道路,能将女...