【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)。

相关内容

热门资讯

山水皆有情!丽江两山一江的千年... 去过丽江、走过虎跳峡的人,大概率都听过哈巴雪山和金沙江的传说。很多人站在峡谷之下,望着奔腾不息的金沙...
活力中国调研行丨“殷”你而来 ... 9月12日,游客在殷墟博物馆“甲骨文展厅”内参观。位于河南省安阳市的殷墟博物馆新馆是首个全景式展现商...
浦江之夜赴美好相逢,第37届上... 9月12日晚,黄浦江畔灯火璀璨,第37届上海旅游节大巡游在外滩中山东一路上演。不少观众早早便来到外滩...
美丽中国丨秋韵紫鹊界 梯田入画... 这是9月11日拍摄的紫鹊界梯田(无人机照片)。 金秋九月,湖南省娄底市新化县紫鹊界梯田稻谷渐次成熟。...
中国之巅奏响《共同的节日》,千... 千吨阻尼器,“迎世赛、游上海旅游节”。9月13日,由上海市文化和旅游局指导推出上海旅游·会客│巅峰之...