2023-08-17力扣每日一题

链接:

1444. 切披萨的方案数

题意:

给定一个矩阵,其中含有多个苹果,需要切割k-1次,每次可以切割多行/多列,需要保证切割两个部分都有苹果,移除靠上/靠右的部分,对留下部分进行后续的切割,求有几种切割方法

解:

男人不能快算法需要快!

这题需要通过两部分节约时间,一部分是动态规划,一部分是前缀和

这好像还是第一次写二维前缀和(好像),主要是要记得移除重复部分,由于每次保留的是靠下/靠左的部分,所以求的是已i j 为起点的右下角和

动态规划部分,我们需要一个三维的DP[k][i][j],分别代表从i j开始的右下角矩阵,成功切割k-1刀的方案数量

初始值是DP[1][i][j]=(sum[i][j] > 0),即这一整块上存在苹果

递推公式需要判断行切和列切,判断条件非常巧妙,是整体苹果数量 > 切割后剩下的苹果数量,公式是整体+=切割后的部分

整体DP[temp][i][j],假设在i2位置进行切割,则判断sum[i][j] > sum[i2][j],若为真即计算DP[temp][i][j]+=DP[temp-1][i2][j],要注意切割后所需的切割数-1

实际代码:

#include
using namespace std;
constexpr static int Mod=1E9+7; 
int ways(vector& pizza, int k)
{
    int lgrow=pizza.size(),lgcol=pizza[0].length();
    vector>sum(lgrow+1,vector(lgcol+1));
    vector>>dp(k+1,vector>(lgrow+1,vector(lgcol+1)));
    //初始化 
    for(int i=lgrow-1;i>=0;i--)
    {
        for(int j=lgcol-1;j>=0;j--)
        {
            sum[i][j]=sum[i+1][j]+sum[i][j+1]-sum[i+1][j+1]+(pizza[i][j]=='A');//二维前缀和 矩阵计算 
            dp[1][i][j]=sum[i][j]>0;
        }
    }
    //dp递推 
    for(int dp_k=2;dp_k<=k;dp_k++)
    {
        for(int i=lgrow-1;i>=0;i--)
        {
            for(int j=lgcol-1;j>=0;j--)
            {
                //行切割
                for(int i2=lgrow-1;i2>i;i2--)
                {
                    if(sum[i][j]>sum[i2][j])//切出来的有苹果
                    {
                        dp[dp_k][i][j]+=dp[dp_k-1][i2][j];
                        dp[dp_k][i][j]%=Mod;
                    }
                }
                
                //列切割
                for(int j2=lgcol-1;j2>j;j2--)
                {
                    if(sum[i][j]>sum[i][j2])//切出来的有苹果
                    {
                        dp[dp_k][i][j]+=dp[dp_k-1][i][j2];
                        dp[dp_k][i][j]%=Mod;
                    }
                }
            }
        }
    }
    
    return dp[k][0][0];
}
int main()
{
    int k;cin>>k;
    vector pizza;string s;
    while(cin>>s) pizza.push_back(s);
    int ans=ways(pizza,k);
    cout<

限制:

  • 1 <= rows, cols <= 50
  • rows == pizza.length
  • cols == pizza[i].length
  • 1 <= k <= 10
  • pizza 只包含字符 'A' 和 '.' 。

你可能感兴趣的:(力扣每日一题,leetcode)