5407. 切披萨的方案数


图片说明
图片说明


设dp[i][j][k]为矩形(i,j),(n,m)内切割了k次的方案数,然后倒推就行。

class Solution {
public:
    int dp[55][55][15];
    int sum[55][55]={0};
    const int mod=1e9+7;
    bool ck(int x1,int y1,int x2,int y2){
        return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]>0;
    }
    int dfs(int x1,int y1,int x2,int y2,int k){
        if(k==0)return 1;
        if(x1==x2&&y1==y2&&k)return 0;
        if(dp[x1][y1][k]!=-1)return dp[x1][y1][k];
        long long ans=0;
        for(int i=x1+1;i<=x2;i++){
            if(ck(x1,y1,i-1,y2)&&ck(i,y1,x2,y2))
            ans+=dfs(i,y1,x2,y2,k-1);
            ans%=mod;
        }
        for(int i=y1+1;i<=y2;i++){
            if(ck(x1,y1,x2,i-1)&&ck(x1,i,x2,y2))
            ans+=dfs(x1,i,x2,y2,k-1);
            ans%=mod;
        }
        return dp[x1][y1][k]=ans;
    }
    int ways(vector<string>& pz, int k) {
        int n=pz.size(),m=pz[0].size();
        memset(dp,-1,sizeof(dp));
        for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
                sum[i][j]=(pz[i-1][j-1]=='A')+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
            }
        }
        if(k==1&&ck(1,1,n,m))return 1;
        if(k==1)return 0;
        return dfs(1,1,n,m,k-1);
    }
};