給你一個 rows x cols 大小的矩形披薩和一個整數 k ,矩形包含兩種字符: ‘A’ (表示蘋果)和 ‘.’ (表示空白格子)。你需要切披薩 k-1 次,得到 k 塊披薩並送給別人。
切披薩的每一刀,先要選擇是向垂直還是水平方向切,再在矩形的邊界上選一個切的位置,將披薩一分爲二。如果垂直地切披薩,那麼需要把左邊的部分送給一個人,如果水平地切,那麼需要把上面的部分送給一個人。在切完最後一刀後,需要把剩下來的一塊送給最後一個人。
請你返回確保每一塊披薩包含 至少 一個蘋果的切披薩方案數。由於答案可能是個很大的數字,請你返回它對 10^9 + 7 取餘的結果。
示例 1:
輸入:pizza = [“A…”,“AAA”,"…"], k = 3
輸出:3
解釋:上圖展示了三種切披薩的方案。注意每一塊披薩都至少包含一個蘋果。
示例 2:
輸入:pizza = [“A…”,“AA.”,"…"], k = 3
輸出:1
1 <= rows, cols <= 50
rows == pizza.length
cols == pizza[i].length
1 <= k <= 10
pizza 只包含字符 ‘A’ 和 ‘.’
f[i][j][k]表示切了k次剩下了(i,j)爲左上角的方塊的方案數
int s1[55][55],s2[55][55],pd[55][55];
int f[55][55][12];
int n,m;
const long long p = 1e9+7;
class Solution {
public:
int ways(vector<string>& pizza, int k) {
n = pizza.size();
m = pizza[0].size();
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
memset(pd,0,sizeof(pd));
memset(f,0,sizeof(f));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
pd[i][j] = s1[i][j] = s2[i][j] = (pizza[i][j]=='A');
for (int i = n-1; i >= 0; i--)
for (int j = m-1; j >= 0; j--) {
s1[i][j] += s1[i][j+1];
s2[i][j] += s2[i+1][j];
}
f[0][0][0] = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int t = 1; t <= k; t++) {
int s = 0;
for (int x = i - 1; x >= 0; x--) {
s += s1[x][j];
if(s)
f[i][j][t] = (f[i][j][t]+f[x][j][t-1])%p;
}
s = 0;
for (int y = j - 1; y >= 0; y--) {
s += s2[i][y];
if (s)
f[i][j][t] = (f[i][j][t]+f[i][y][t-1])%p;
}
}
int ans = 0;
for (int i = n-1; i >= 0; i--)
for (int j = m-1; j >= 0; j--) {
pd[i][j] |= pd[i+1][j]|pd[i][j+1];
if (pd[i][j]) {
ans = (ans+f[i][j][k-1]) % p;
}
}
return ans;
}
};