[leetcode 1444]切披薩的方案數(動態規劃)

給你一個 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;
        
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章