Given a rectangular pizza represented as a rows x cols matrix containing the following characters: ‘A’ (an apple) and ‘.’ (empty cell) and given the integer k. You have to cut the pizza into k pieces using k-1 cuts.

For each cut you choose the direction: vertical or horizontal, then you choose a cut position at the cell boundary and cut the pizza into two pieces. If you cut the pizza vertically, give the left part of the pizza to a person. If you cut the pizza horizontally, give the upper part of the pizza to a person. Give the last piece of pizza to the last person.

Return the number of ways of cutting the pizza such that each piece contains at least one apple. Since the answer can be a huge number, return this modulo 10^9 + 7.

Example 1:

Input: pizza = [“A…”,“AAA”,“…”], k = 3
Output: 3

Explanation: The figure above shows the three ways to cut the pizza. Note that pieces must contain at least one apple.

Example 2:

Input: pizza = [“A…”,“AA.”,“…”], k = 3
Output: 1

Example 3:

Input: pizza = [“A…”,“A…”,“…”], k = 1
Output: 1

Constraints:

  • 1 <= rows, cols <= 50
  • rows == pizza.length
  • cols == pizza[i].length
  • 1 <= k <= 10
  • pizza consists of characters ‘A’ and ‘.’ only.

我在任意处切一刀, 只要保证剩余的部分可以再分成 k - 1 份即可

假设剩余的披萨的顶部为 top, 左侧为 left, 那 dp[top][left]就应该等于, 对于任意 top < r <= bottom
水平切的方法数量为, horizontal = sum(dp[r][left]), 对于任意 left < c <= right, 垂直的切法数量为 vertical = sum(dp[top][c]), horizontal + vertical 即为全部的切法。

但是不是每个位置我们都可以下刀的, 我们需要检查切下来拿去分的部分(上半部分或者左半部分)上是不是有苹果, 而且还要保证剩下的部分能够分。 剩余部分好处理, 如果不够分我们直接在递归的过程中返回 0 即可。检查拿去分的部分上面是否有苹果, 我们借助二维的 prefix sum 可以解决



use std::collections::HashMap;const M: i64 = 1000000007;impl Solution {fn dp(prefix_sum: &Vec<Vec<i32>>, k: i32, top: usize, left: usize, cache: &mut HashMap<(i32, usize, usize), i64>) -> i64 {if k == 1 {return if Solution::get_apple_count(prefix_sum, top, left, prefix_sum.len() - 1, prefix_sum[0].len() - 1) > 0 {1} else {0};}if let Some(&c) = cache.get(&(k, top, left)) {return c;}let mut ans = 0;for bottom in top + 1..prefix_sum.len() {if Solution::get_apple_count(prefix_sum, top, left, bottom, prefix_sum[0].len() - 1) > 0 {ans += Solution::dp(prefix_sum, k - 1, bottom, left, cache) % M;ans %= M;}}for right in left + 1..prefix_sum[0].len() {if Solution::get_apple_count(prefix_sum, top, left, prefix_sum.len() - 1, right) > 0 {ans += Solution::dp(prefix_sum, k - 1, top, right, cache) % M;ans %= M;}}cache.insert((k, top, left), ans);ans}fn get_apple_count(prefix_sum: &Vec<Vec<i32>>, top: usize, left: usize, bottom: usize, right: usize) -> i32 {prefix_sum[bottom][right] - prefix_sum[bottom][left] - prefix_sum[top][right] + prefix_sum[top][left]}pub fn ways(pizza: Vec<String>, k: i32) -> i32 {let pizza: Vec<Vec<char>> = pizza.into_iter().map(|s| s.chars().collect()).collect();let mut prefix_sum = vec![vec![0; pizza[0].len() + 1]; pizza.len() + 1];for r in 0..pizza.len() {for c in 0..pizza[0].len() {prefix_sum[r + 1][c + 1] = prefix_sum[r][c + 1] + prefix_sum[r + 1][c] - prefix_sum[r][c] + if pizza[r][c] == 'A' { 1 } else { 0 };}}Solution::dp(&prefix_sum, k, 0, 0, &mut HashMap::new()) as i32}
}

LeetCode每日一题(1444. Number of Ways of Cutting a Pizza)相关推荐

  1. leetcode每日刷题计划-简单篇day8

    leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...

  2. Leetcode每日一题:171.excel-sheet-column-number(Excel表列序号)

    思路:就是168题的反命题,进制的方式完美解决: Leetcode每日一题:168.excel-sheet-column-title(Excel表名称) class Solution {public: ...

  3. 【LeetCode每日一题】1723. 完成所有工作的最短时间

    [LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...

  4. leetcode每日一题--雀巢原理;抽屉算法;Quorum机制;分布式应用

    leetcode每日一题 539. 最小时间差 示例 1: 输入:timePoints = ["23:59","00:00"] 输出:1 示例 2: 输入:ti ...

  5. LeetCode每日一题——1812. 判断国际象棋棋盘中一个格子的颜色

    LeetCode每日一题系列 题目:1812. 判断国际象棋棋盘中一个格子的颜色 难度:简单 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给你一个坐标 coordinates ...

  6. 【LeetCode每日一题】——109.有序链表转换二叉搜索树

    文章目录 一[题目类别] 二[题目难度] 三[题目编号] 四[题目描述] 五[题目示例] 六[题目提示] 七[解题思路] 八[时间频度] 九[代码实现] 十[提交结果] 一[题目类别] 二叉树 二[题 ...

  7. leetcode每日一题·救生艇问题(Python)

    leetcode每日一题·救生艇问题(Python) 问题描述 题目入口 题目思路 首先分析问题,一个船最多坐两人,因此我们可以把这个问题看作两两组合的问题,并且如果最重的那个人和最轻的人加起来大于l ...

  8. LeetCode每日一题——904. 水果成篮

    LeetCode每日一题系列 题目:904. 水果成篮 难度:普通 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 你正在探访一家农场,农场从左到右种植了一排果树.这些树用一个整 ...

  9. LeetCode每日一题打卡组队监督!刷题群!

    近 2000 人已经加入共同刷题啦! 群友每天都会在群里给大家讲解算法题 每周日「负雪明烛」组织直播讲题 我相信来看我博客的大部分人都是通过LeetCode刷题过来的.最近发现LeetCode中文网站 ...

最新文章

  1. cocos2d-lua 3.5 android搭建常见错误
  2. 《1---关于解决MySQL在控制台插入中文乱码问题》
  3. android查看Logcat
  4. linux 切换python版本_linux下多个python版本切换如何设置
  5. 反积分饱和 程序_用抗积分饱和PID控制传递函数为G(s)的被控对象
  6. 谷歌浏览器 检查功能_谷歌Chrome浏览器添加新功能,爱”吃“内存有应对之策?...
  7. Java开源项目Hibernate获得成功的十大理由
  8. 【2022美赛F奖】B题:水电共享
  9. oracle 中的or,oracle语句查询 or和and
  10. 湘源控规计算土石方流程
  11. ftp,fxp服务器误删代码如何恢复
  12. python代码,用于获取mp3部分信息并存入MySQL中
  13. 直播源码部署直播软件系统搭建!
  14. linux系统篇 -- 一、系统概要
  15. “华夏”二字之由来——我们为何称为“华夏”
  16. Android5.0录屏
  17. 5.5 图层样式的复制和粘贴 [原创Ps教程]
  18. AUTOCAD——怎么画轴测图
  19. 微信小程序开发之官方文档学习(一)
  20. iOS 4.3.5 红雪不完美越狱教程

热门文章

  1. android 轮播coverflow,vue-awesome-swiper 3D coverflow effect 使用时每个slider发生错位
  2. 雷蛇驱动显示连接不到服务器,雷蛇驱动个性设置_雷蛇驱动打不开怎么办
  3. (简单易学DNS反向解析
  4. linux中怎么运行chkdsk,计算机每次启动过程中总会执行磁盘检查CHKDSK什么问题?怎么解决?...
  5. 2014年开年计划 - 不积跬步无以至千里
  6. Java http发送post请求
  7. android 多行 输入框,EditTextView Android中的多行字符串(Multiline String in EditTextView Android)...
  8. TI Driver---EDMA
  9. 360°可旋转线上沙盘,VR看盘不错过每一个细节
  10. “我”Java程序员今年30岁,还有五年“寿命”所谓的中年危机?