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 ];

       结束。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言:初阶测试错题(查漏补缺)

题一&#xff1a;字符串倒置 示例1 输入 I like beijing. 输出 beijing. like I 思路一&#xff1a; 定义字符串数组arr[ ] ,利用gets()将要倒置的字符串输入&#xff0c;记录字符串长度len&#xff0c;此时写一个逆置函数Inversion()&#xff0c;第一步将整个字符串逆置&…

原生微信小程序自定义picker多列选择器:picker写法用法

前言: 最近用原生微信小程序写法写医疗相关项目微信小程序&#xff0c;在编辑个人资料的时候&#xff0c;需要很多选择器&#xff0c;比如城市地区选择器&#xff0c;职业职称选择器&#xff0c;科室选择器&#xff0c;学校选择器&#xff0c;学历选择器&#xff0c;年份日期选…

RabbitMq交换机类型介绍

RabbitMq交换机类型介绍 在RabbitMq中&#xff0c;生产者的消息都是通过交换器来接收&#xff0c;然后再从交换器分发到不同的队列&#xff0c;再由消费者从队列获取消息。这种模式也被成为“发布/订阅”。 分发的过程中交换器类型会影响分发的逻辑。 直连交换机&#xff1a…

Vue-5.编译器Idea

Vue专栏&#xff08;帮助你搭建一个优秀的Vue架子&#xff09; Vue-1.零基础学习Vue Vue-2.Nodejs的介绍和安装 Vue-3.Vue简介 Vue-4.编译器VsCode Vue-5.编译器Idea Vue-6.编译器webstorm Vue-7.命令创建Vue项目 Vue-8.Vue项目配置详解 Vue-9.集成&#xff08;.editorconfig、…

公网远程连接Redis数据库「内网穿透」

文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 前言 洁洁的个人主页 我就问你有没有发挥&#xff0…

wsl没有响应,wsl启动失败,docker启动失败

wsl的相关问题记录和解决 问题一&#xff1a;cmd命令窗口输入wsl后没有响应&#xff0c;会卡住&#xff0c;类似如图 排查&#xff1a; 输入 wsl -l -v看是否有东西输出&#xff1b;我的电脑没有东西输出&#xff0c;依旧是卡住;有内容请重启试试从开始菜单打开&#xff0c;点…

CSS 背景属性

前言 背景属性 属性说明background-color背景颜色background-image背景图background-repeat背景图平铺方式background-position背景图位置background-size背景图缩放background-attachment背景图固定background背景复合属性 背景颜色 可以使用background-color属性来设置背景…

(五)、深度学习框架源码编译

1、源码构建与预构建&#xff1a; 源码构建&#xff1a; 源码构建是通过获取软件的源代码&#xff0c;然后在本地编译生成可执行程序或库文件的过程。这种方法允许根据特定需求进行配置和优化&#xff0c;但可能需要较长的时间和较大的资源来编译源代码。 预构建&#xff1a; 预…

算法通关村第十关 | 归并排序

1. 归并排序原理 归并排序&#xff08;MERARE-SORT&#xff09;简单来说就是将大的序列先视为若干个比较小的数组&#xff0c;分成比较小的结构&#xff0c;然后是利用归并的思想实现的排序方法&#xff0c;该算法采用经典的分治策略&#xff08;分就是将问题分成一些小的问题分…

数据库--SQL关键字的执行顺序

数据库相关链接&#xff1a; 数据库--数据类型&#xff1a;http://t.csdn.cn/RtqMD 数据库--三大范式、多表查询、函数sql&#xff1a;http://t.csdn.cn/udJSG 数据库--MySQL增删改查&#xff1a;http://t.csdn.cn/xkiti 一、一条sql语句通常包括&#xff1a; select fro…

idea 本地版本控制 local history

idea 本地版本控制 local history 如何打开 1 自定义快捷键 settings->keymap->搜索框输入 show history -》Add Keyboard Shortcut -》设置为 CtrlAltL 2 右键文件-》local history -》show history 新建文件 版本1&#xff0c;creating class com.geekmice…这个是初…

OpenCV-Python中的图像处理-视频分析

OpenCV-Python中的图像处理-视频分析 视频分析Meanshift算法Camshift算法光流Lucas-Kanade Optical FlowDense Optical Flow 视频分析 学习使用 Meanshift 和 Camshift 算法在视频中找到并跟踪目标对象: Meanshift算法 Meanshift 算法的基本原理是和很简单的。假设我们有一堆…

esp32c3 micropython oled实时天气信息

目录 简介 效果展示 代码 main.py ssd1306.py font.py 实现思路 简介 合宙esp32c3 micropython框架&#xff0c;只支持128*64 I2C oled ssd1306驱动我优化过的&#xff0c;与其他的不一样&#xff0c;为避免出错&#xff0c;使用我的驱动 把下面两个py文件放入单片机内…

提高批量爬虫工作效率

大家好&#xff01;作为一名专业的爬虫程序员&#xff0c;我今天要和大家分享一些关于提高批量爬虫工作效率的实用技巧。无论你是要批量采集图片、文本还是视频数据&#xff0c;这些经验都能帮助你在大规模数据采集中事半功倍。废话不多说&#xff0c;让我们开始吧&#xff01;…

【C++深入浅出】初识C++中篇(引用、内联函数)

目录 一. 前言 二. 引用 2.1 引用的概念 2.2 引用的使用 2.3 引用的特性 2.4 常引用 2.5 引用的使用场景 2.6 传值、传引用效率比较 2.7 引用和指针的区别 三. 内联函数 3.1 内联函数的概念 3.2 内联函数的特性 一. 前言 上期说道&#xff0c;C是在C的基础之上&…

Java多态详解(1)

多态 多态的概念 所谓多态&#xff0c;通俗地讲&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 比如&#xff1a; 这一时间爆火的“现代纪录片”中&#xff0c;麦克阿瑟总是对各种“名人”有不同的评价&…

第 4 章 链表(1)

4.1链表(Linked List)介绍 链表是有序的列表&#xff0c;但是它在内存中是存储如下 小结: 链表是以节点的方式来存储,是链式存储每个节点包含 data 域&#xff0c; next 域&#xff1a;指向下一个节点.如图&#xff1a;发现链表的各个节点不一定是连续存储.链表分带头节点的链…

使用git rebase 之后的如何恢复到原始状态

我们常常喜欢使用git rebase去切换分支提交代码,操作流程就是: 先切换分支:比如当前是master 我们修改了一堆代码产生一个commit id :5555555567777 那么我们常常比较懒就直接切换了:git checkout dev 然后呢?使用命令git rebase 5555555567777,想把这笔修改提交到d…

SpringBoot-lombok

为什么要使用lombok? Lombok是一个通过注解以达到减少代码的Java库,如通过注解的方式减少getter,setter方法,构造方法等。通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法&#xff0c;并可以自动化生成日志变量&#xff0c;简化java开发、提高…

[uni-app] uview封装Popup组件,处理props及v-model的传值问题

文章目录 需求及效果遇到的问题解决的办法偷懒的写法 需求及效果 uView(1.x版本)中, 有Pop弹出层的组件, 现在有个需求是,进行简单封装,有些通用的设置不想每次都写(比如 :mask-custom-style"{background: rgba(0, 0, 0, 0.7)}"这种) 然后内部内容交给插槽去自己随…