Leetcode每日一题:1444. 切披萨的方案数(2023.8.17 C++)

目录

1444. 切披萨的方案数

题目描述:

实现代码与解析:

二维后缀和  + 动态规划

原理思路:


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

示例 3:

输入:pizza = ["A..","A..","..."], k = 1
输出:1

提示:

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

实现代码与解析:

二维后缀和  + 动态规划

class Solution {
public:
    int ways(vector<string>& pizza, int k) {

        int m = pizza.size(), n = pizza[0].size(), mod = 1e9 + 7;
        vector<vector<vector<int>>> f(k, vector<vector<int>>(m, vector<int>(n)));

        vector<vector<int>> apples(m + 1, vector<int>(n + 1)); // 后缀和

        // 后缀和 与 初始化dp数组
        for (int i = m - 1; i >= 0; i--)
        {
            for (int j = n - 1; j >= 0; j--)
            {
                apples[i][j] = apples[i + 1][j] + apples[i][j + 1] - apples[i + 1][j + 1] + (pizza[i][j] == 'A');
                f[0][i][j] = apples[i][j] > 0;
            }
        } 

        for (int kk = 1; kk < k; kk++)
        {
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    // 选择此刀的切割位置

                    // 水平切, 遍历切的位置
                    for (int a = i + 1; a < m; a++)
                    {
                        // 上面的一块中至少要有一个苹果
                        if (apples[i][j] > apples[a][j])
                        {
                            f[kk][i][j] = (f[kk][i][j] + f[kk - 1][a][j]) % mod;
                        }
                    }
                
                    // 垂直切
                    for (int b = j + 1; b < n; b++)
                    {
                        // 左侧块中至少有一个苹果
                        if (apples[i][j] > apples[i][b])
                        {
                            f[kk][i][j] = (f[kk][i][j] + f[kk - 1][i][b]) % mod;
                        }
                    }
                }
            }
        }
        
        return f[k - 1][0][0];
    }
};

原理思路:

        apples 数组,后缀和用于记录一块披萨中的苹果数量,用一块中的左上角来代替此块含有的苹果数。

        此题的关键是,dp[ k ][ i ][ j ] 的含义代表还剩下 k 刀没切,剩下的是左上角为 i ,j 的披萨状态时的切割方案总数。这是我自己的理解,力扣上dp数组定义的含义感觉不如我这样写和解释更直观,不过原理肯定是一样的。

        知道dp数组的含义,就很好写了。

        首先计算 apples 数组,这个就不用解释了,不会的话,建议去学习一下前缀和,二维前缀和的基础算法就行,同时初始化一下dp。

        初始化dp数组:显然在还需要切0刀,剩下最后一块披萨中有苹果时,表示切好了,是一种情况,赋值为1,否则不成立赋值为0;

f[0][i][j] = apples[i][j] > 0;

        遍历顺序:一定是先遍历切割刀数,因为就比如一个形状披萨状态下,切两刀肯定需要切一刀的状态递推而来,后面根据递推式也能看出来。

        递推方程:两种切法分类讨论:

        水平切:肯定是从第一行下边开始切,总不能切空气吧,所以是 i + 1 开始遍历,然后切完后上面的那块中一定要有苹果,所以需要判断一下,切完此刀后,剩下的大块需要再切 kk - 1刀,我们就不用再去遍历了,dp数组含义就是这个,根据这个写出递推式。

                递推式:f[ kk ][ i ][ j ] = (f[ kk ][ i ][ j ] + f[ kk - 1 ][ a ][ j ]) % mod;

        垂直切:与水平切同理,直接给出递推式:

                递推式:f[ kk ][ i ][ j ] = (f[ kk ][ i ][ j ] + f[ kk - 1 ][ i ][ b ]) % mod;

       最后,返回结果,显然,在初始状态还剩切k - 1刀时是我们需要的结果状态。

       return f[ k - 1 ][ 0 ][ 0 ];

       结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/79408.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BC136 KiKi去重整数并排序

给定一个整数序列&#xff0c;KiKi想把其中的重复的整数去掉&#xff0c;并将去重后的序列从小到大排序输出。 输入描述 第一行&#xff0c;输入一个整数n&#xff0c;表示序列有n个整数。 第二行输入n个整数&#xff08;每个整数大于等于1&#xff0c;小于等于1000&#xf…

【日常积累】Linux之init系统学习

init系统简介: Linux 操作系统的启动首先从 BIOS 开始&#xff0c;接下来进入 boot loader&#xff0c;由 bootloader 载入内核&#xff0c;进行内核初始化。内核初始化的最后一步就是启动 pid 为 1 的 init 进程&#xff0c;这个进程是系统的第一个进程&#xff0c;它负责产生…

企望制造ERP系统 RCE漏洞复现

0x01 产品简介 企望制造纸箱业erp系统由深知纸箱行业特点和业务流程的多位IT专家打造&#xff0c;具有国际先进的管理方式&#xff0c;将现代化的管理方式融入erp软件中&#xff0c;让企业分分钟就拥有科学的管理经验。 erp的功能包括成本核算、报价定价、订单下达、生产下单、…

编程语言学习笔记-架构师和工程师的区别,PHP架构师之路

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

Unity游戏源码分享-中国象棋Unity5.6版本

Unity游戏源码分享-中国象棋Unity5.6版本 项目地址&#xff1a; https://download.csdn.net/download/Highning0007/88215699

TCP拥塞控制简单理解

1.TCP的控制机制 序号 TCP通过序号可以实现一下几个功能&#xff1a; 1.确认应答处理。发送端收到接收端的确认应答&#xff0c;可以得知某些数据包被接收端接收了 2.顺序控制。接收端可以利用序号对接收到的报文进行排序 3.重发控制。如果发送端没有收到确认应答&#xff0c…

vue项目引入antDesignUI组件

快速安装ant-design-vue并配置&#xff0c;vue2.0 antDesign1.7.8 第一步&#xff1a;安装ant-deisgn-vue 1.7.8 npm install ant-design-vue1.7.8 --save第二步&#xff1a;配置package.json文件&#xff0c;将依赖写入后&#xff0c;npm install 安装依赖 "dependenc…

智慧建筑工地平台,通过信息化技术、物联网、人工智能技术,实现对施工全过程的实时监控、数据分析、智能管理和优化调控

智慧工地是指通过信息化技术、物联网、人工智能技术等手段&#xff0c;对建筑工地进行数字化、智能化、网络化升级&#xff0c;实现对施工全过程的实时监控、数据分析、智能管理和优化调控。智慧工地的建设可以提高工地的安全性、效率性和质量&#xff0c;降低施工成本&#xf…

Maven官网下载配置新仓库

1.Maven的下载 Maven的官网地址&#xff1a;Maven – Download Apache Maven 点击Download&#xff0c;查找 Files下的版本并下载如下图&#xff1a; 2.Maven的配置 自己在D盘或者E盘创建一个文件夹&#xff0c;作为本地仓库&#xff0c;存放项目依赖。 将下载好的zip文件进行解…

react 生命周期方法

组件的生命周期 每个组件都包含 “生命周期方法”&#xff0c;你可以重写这些方法&#xff0c;以便于在运行过程中特定的阶段执行这些方法。你可以使用此生命周期图谱作为速查表。在下述列表中&#xff0c;常用的生命周期方法会被加粗。其余生命周期函数的使用则相对罕见。 挂…

LLM - 大模型评估指标之 BLEU

目录 一.引言 二.BLEU 简介 1.Simple BLEU 2.Modified BLEU 3.Modified n-gram precision 4.Sentence brevity penalty 三.BLEU 计算 1.计算句子与单个 reference 2.计算句子与多个 reference 四.总结 一.引言 机器翻译的人工评价广泛而昂贵&#xff0c;且人工评估可…

Spark第三课

1.分区规则 1.分区规则 shuffle 1.打乱顺序 2.重新组合 1.分区的规则 默认与MapReduce的规则一致,都是按照哈希值取余进行分配. 一个分区可以多个组,一个组的数据必须一个分区 2. 分组的分区导致数据倾斜怎么解决? 扩容 让分区变多修改分区规则 3.HashMap扩容为什么必须…

Jetpack Compose:探索声明式UI开发的未来

Jetpack Compose&#xff1a;探索声明式UI开发的未来 1. 引言 在移动应用开发领域&#xff0c;用户界面&#xff08;UI&#xff09;开发一直是开发过程中的关键挑战之一。传统的UI开发方式往往涉及大量繁琐的布局代码、手动管理状态和事件处理&#xff0c;不仅容易引发错误&a…

linux第三阶段--第三方软件(一)MySQL的概述和二进制安装(官网版)

MySQL介绍及安装 一、MySQL概述 DB2 POSTGRE-SQL 1、关系型数据库与非关系型数据库 RDBMS&#xff08;relational database management system&#xff09;&#xff0c;既关系型数据库管理系统。 简单来说&#xff0c;关系型数据库&#xff0c;是指采用了二维表格来组织数…

Vue 项目运行 npm install 时,卡在 sill idealTree buildDeps 没有反应

解决方法&#xff1a;切换到淘宝镜像。 以下是之前安装的 xmzs 包&#xff0c;用于控制切换淘宝镜像。 该截图是之前其他项目切换淘宝镜像的截图。 切换镜像后&#xff0c;顺利执行 npm install 。

TDD(测试驱动开发)?

01、前言 很早之前&#xff0c;曾在网络上见到过 TDD 这 3 个大写的英文字母&#xff0c;它是 Test Driven Development 这三个单词的缩写&#xff0c;也就是“测试驱动开发”的意思——听起来很不错的一种理念。 其理念主要是确保两件事&#xff1a; 确保所有的需求都能被照…

Python查找交作业人数

写在前面&#xff1a; 利用Python统计文件数量&#xff0c;能够高效快捷地收集作业&#xff01; 一、问题&#xff1a;获取test文件夹下的所有文件 二、Python中os.listdir()函数的用法 &#xff08;一&#xff09;os.listdir()函数的基本用法 os.listdir()函数的基本语法如…

【Realtek sdk-3.4.14b】RTL8197F+RTL8812F欧洲屏蔽5G天气雷达信道DFS信道120、124、128方法

需求描述 对于欧洲国家来说,默认支持DFS信道,但是有三个信道比较特殊,是天气雷达信道,如下图所示120、124、128,天气雷达信道有个特点就是在信号可以发射之前需要检测静默15min,如果信道自动选择到了天气雷达信道,就会有15min的时间无法连接到WiFi热点,严重影响用户体验…

Java接口压力测试—如何应对并优化Java接口的压力测试

导言 在如今的互联网时代&#xff0c;Java接口压力测试是评估系统性能和可靠性的关键一环。一旦接口不能承受高并发量&#xff0c;用户体验将受到严重影响&#xff0c;甚至可能导致系统崩溃。因此&#xff0c;了解如何进行有效的Java接口压力测试以及如何优化接口性能至关重要…

【数学建模】-- 数学规划模型

概述&#xff1a; 什么是数学规划&#xff1f; 数学建模中的数学规划是指利用数学方法和技巧对问题进行数学建模&#xff0c;并通过数学规划模型求解最优解的过程。数学规划是一种数学优化方法&#xff0c;旨在找到使目标函数达到最大值或最小值的变量取值&#xff0c;同时满足…