首页 > 其他分享 >力扣1444.切割后面积最大的蛋糕(贪心)

力扣1444.切割后面积最大的蛋糕(贪心)

时间:2023-10-28 11:26:38浏览次数:28  
标签:vector verticalCuts int horizontalCuts long 力扣 1444 蛋糕 贪心

矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCuts 和 verticalCuts,其中:

  •  horizontalCuts[i] 是从矩形蛋糕顶部到第  i 个水平切口的距离
  • verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离

请你按数组 horizontalCuts  verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果  109 + 7 取余 后返回。

 

示例 1:

输入:h = 5, w = 4, horizontalCuts = [1,2,4], verticalCuts = [1,3]
输出:4 
解释:上图所示的矩阵蛋糕中,红色线表示水平和竖直方向上的切口。切割蛋糕后,绿色的那份蛋糕面积最大。

 

示例 2:

输入:h = 5, w = 4, horizontalCuts = [3,1], verticalCuts = [1]
输出:6
解释:上图所示的矩阵蛋糕中,红色线表示水平和竖直方向上的切口。切割蛋糕后,绿色和黄色的两份蛋糕面积最大。

 

示例 3:

输入:h = 5, w = 4, horizontalCuts = [3], verticalCuts = [3]
输出:9

 

 

提示:

  • 2 <= h, w <= 109
  • 1 <= horizontalCuts.length <= min(h - 1, 105)
  • 1 <= verticalCuts.length <= min(w - 1, 105)
  • 1 <= horizontalCuts[i] < h
  • 1 <= verticalCuts[i] < w
  • 题目数据保证 horizontalCuts 中的所有元素各不相同
  • 题目数据保证 verticalCuts 中的所有元素各不相同

1.分治法:每次切割都将原来的图分割成两部分,然后对于被分割出来的两部分再进行分割,直到不能分割为止。剪枝:先对分割序列进行排序,这样就可以实现:先从上往下横着切,再从左到右竖着切。这样一来,对于横切部分,划分成上下两半,(若升序排序)上半边已经不会再被切割了,所以对上半边进行递归的时候可以把水平切割队列置空;对于竖切部分同理。

 1 class Solution
 2 {
 3 public:
 4     vector<int> none;
 5     long long max_area = 0;
 6     long long mod = 1e9 + 7;
 7     void divideArea(long long bx, long long by, long long ex, long long ey, vector<int> horizontalCuts, vector<int> verticalCuts)
 8     { // bx、by为区域左上角坐标,ex、ey为区域右下角坐标
 9 
10         if (!horizontalCuts.empty())
11         {
12             int row = horizontalCuts.front();
13             horizontalCuts.erase(horizontalCuts.begin());
14             divideArea(bx, by, row, ey, none, verticalCuts);           // 上部
15             divideArea(row, by, ex, ey, horizontalCuts, verticalCuts); // 下部
16         }
17         else if (!verticalCuts.empty())
18         {
19             int column = verticalCuts.front();
20             verticalCuts.erase(verticalCuts.begin());
21             divideArea(bx, by, ex, column, none, none);         // 左部
22             divideArea(bx, column, ex, ey, none, verticalCuts); // 右部
23         }
24         else
25         { // 切割完毕,更新最大面积
26             max_area = max(max_area, (ey - by) * (ex - bx));
27         }
28     }
29     int maxArea(int h, int w, vector<int> &horizontalCuts, vector<int> &verticalCuts)
30     {
31         sort(horizontalCuts.begin(), horizontalCuts.end());
32         sort(verticalCuts.begin(), verticalCuts.end());
33         divideArea(0, 0, h, w, horizontalCuts, verticalCuts);
34         return max_area % mod;
35     }
36 };

该代码不能通过最后一组用例,因为空间复杂度爆了,暂时没找到优化的点,仅供思路参考。

 

2.贪心法:我们注意到他的每次切割都是水平或垂直的完全切割,也就是说每次不同方向切割都能相互影响(例如横切过2刀之后,蛋糕被分成了三块,此时竖切一刀,这时的三块蛋糕都会同时受到影响),所以我们只需考虑横切完后的最大间距和竖切完后的最大间距,他们围成的面积就是最大的。

 1 class Solution
 2 {
 3 public:
 4     long long mod = 1e9 + 7;
 5 
 6     long long maxInterval(vector<int> arr, int border)
 7     {
 8         int mmax = border - *arr.rbegin(); //初值为最后一块的长度
 9         int pre = 0;
10         for (int i : arr)
11         {
12             mmax = max(i - pre, mmax);
13             pre = i;
14         }
15         return mmax;
16     }
17     int maxArea(int h, int w, vector<int> &horizontalCuts, vector<int> &verticalCuts)
18     {
19         sort(horizontalCuts.begin(), horizontalCuts.end());
20         sort(verticalCuts.begin(), verticalCuts.end());
21         return maxInterval(horizontalCuts, h) * maxInterval(verticalCuts, w) % mod;
22     }
23 };

 

标签:vector,verticalCuts,int,horizontalCuts,long,力扣,1444,蛋糕,贪心
From: https://www.cnblogs.com/coderhrz/p/17793832.html

相关文章

  • Day59 | 力扣695:岛屿的最大面积
    力扣链接写在前面这道题和200.岛屿数量很像,只不过200.岛屿数量是求岛屿总个数,这道题是求最大的岛屿面积,基本代码逻辑是一样的,只不过具体处理细节有一点不一样思路在主函数maxAreaOfIsland中遍历,遇到岛屿temp就计数为1,然后进入dfs函数,每次遍历到一个岛屿,temp就加1,用变量tem......
  • 贪心法求解问题
    一、背包问题1.1问题描述  设有编号为1、2、......、n的n个物品,它们的重量分别为w1、w2、......、wn,价值分别为v1、v2、......、vn,其中wi和vi均为正数,有一个背包可以懈怠的最大重量不超过W。求解目标是在不超过背包附中的前提下使背包装入的总价值最大(即效益最大化)。与0/1背......
  • 你是不是瞧不起力扣
    leetcode「10·24」程序员节编程竞赛计算子集给你三个整数\(n,k,m\)。定义\(S=\{i\mid1\lei\lenm+k,i\in\mathbbZ\}\)请返回一个下标从\(0\)开始、长度为\(m\)的数组answer,其中answer[i]表示符合下列条件集合\(T\)的个数。集合\(T\)是集合\(S\)的子集......
  • 贪心算法
    顾名思义,贪心,即永远选择当下情况下最佳的结果,也就是所谓的局部最优解。该算法寄希望于局部最优解的堆积可以形成总体上的最优算法。注意:可以使用反证法来判断贪心算法是否可以计算出最优路径。注:大部分有限选择的情况都可以通过有限状态机解决。......
  • 【基础算法】- 贪心
    贪心定义贪心算法适用于最优子结构问题。意思是问题在分解成子问题来解决时,子问题的最优解能递推到最终问题的最优解。常见的符合这种性质的问题如:「我们将XXX按照某某顺序排序,然后按某种顺序(例如从小到大)选择。」「我们每次都取XXX中最大/小的东西,并更新XXX。」但比......
  • Codeforces Round 905 (Div. 2) D1. Dances (Easy version)(贪心+二分)
    CodeforcesRound905(Div.2)D1.Dances(Easyversion)思路:对于\(a\),它的头默认为\(1\),则\(a_0\)=\(1\)对于排完序的\(a\)与\(b\)数组最优为从\(a\)的结尾删除,从\(b\)的开头删除二分保留位数,删去\(n-mid\)位,即\(a\)从\(0\)开始,\(b\)从\(k\)(\(k=n-......
  • 力扣每日一题+python知识点回顾(六)
    力扣题目:老人的数目(题号:2678)给你一个下标从0开始的字符串details。details中每个元素都是一位乘客的信息,信息用长度为15的字符串表示,表示方式如下:前十个字符是乘客的手机号码。接下来的一个字符是乘客的性别。接下来两个字符是乘客的年龄。最后两个字符是乘客的座位......
  • 力扣每日一题+python知识点回顾(五)
    力扣题目:做菜顺序(题号:1402)一个厨师收集了他n道菜的满意程度satisfaction,这个厨师做出每道菜的时间都是1单位时间。一道菜的「like-time系数」定义为烹饪这道菜结束的时间(包含之前每道菜所花费的时间)乘以这道菜的满意程度,也就是time[i]*satisfaction[i]。返回厨师在准备了一......
  • 力扣每日一题+python知识点回顾(四)
    力扣题目:统计无向图中无法互相到达点对数(题号:2316)给你一个整数n,表示一张无向图中有n个节点,编号为0到n-1。同时给你一个二维整数数组edges,其中edges[i]=[ai,bi]表示节点ai和bi之间有一条无向边。请你返回无法互相到达的不同点对数目。示例一:输入:n=3,edges=[[0,1],[0,2......
  • 算法笔记(5)贪心算法
    原发表于我的博客贪心算法贪心与其说是一种算法,不如说一种思想。贪心思想,顾名思义,就是总是做出当前最好的选择,这种方式可能在全局上不是最好的结果,但是在一些题目中就可以直接用。最简单的例子就是“货比三家”,在生活中,我们买东西时都会挑性价比最优的,这就是一种贪心。贪心算......